Multiple managers in single module - Front- & Back-End Development - Front- & Back-End Development - Progress Community
 Front- & Back-End Development

Multiple managers in single module

  • Multiple managers in single module
  • Hello

    I created module with some data items and managers. I then created multiple managers and one open access data provider, with backend pages.

    Then:
    1. I start sitefinity.
    2. I install module, pages occurs in menu. 
    3. I click on one of the items in menu(for example products list) and it works fine. 
    4. I try one of the others items in menu(like card list) and javascript throws error _set_title() is undefined).
    If I uninstall module and install again, I fall in 2nd step again.
    5. In logs there is error in line:
    public static CardsManager GetManager(string providerName, string transactionName)

    return ManagerBase<ProductsDataProvider>.GetManager<CardsManager>(providerName, transactionName);


    Resolution of the dependency failed, type = "xxx.Data.CardsManager", name = "OPENACCESSDATAPROVIDER". 
    Exception occurred while: while resolving. Exception is: InvalidOperationException - The type String cannot be constructed. 
    You must configure the container to supply this value. 
    ----------------------------------------------- 
    At the time of the exception, the container was: Resolving xxx.Data.CardsManager,OPENACCESSDATAPROVIDER Resolving parameter "providerName" 
    of constructor xxx.Data.CardsManager(System.String providerName, System.String transactionName) Resolving System.String,(none)

    The error occurs durring module installation if I return all managers in overriden Managers property:
    public override Type[] Managers
           
                get return new Type[]  
                    typeof(ProductsManager),
                    typeof(CardsManager),
                    typeof(PersonTypesManager),
                    typeof(FiltersManager),
                    typeof(QuoteOfTheDaysManager)
                ;
           


    Stack trace in this case is:
     at Telerik.Sitefinity.Data.ManagerBase.GetManager(Type managerType, String providerName)
       at Telerik.Sitefinity.Data.ManagerBase.GetManager(Type managerType)
       at Telerik.Sitefinity.Services.ModuleBase.EnsureManagersInitialized()
       at Telerik.Sitefinity.Services.SystemManager.InitializeModule(ModuleSettings settings, InstallContext installContext, Nullable`1 start, Boolean skipLoading)



    Implemenation looks like this:

    I have ProductItem, CardItem, FilterItem, PersonTypeItem and QuoteOfTheDayItem.
    [Persistent(IdentityField = "contentId")]
    [DataContract(Namespace = "xxx.Data.Model", Name = "CardItem")]
    [ManagerType(typeof(CardsManager))]
    //[ManagerType("xxx.Data.CardsManager, xxx")]
    public class CardItem : Content, IApprovalWorkflowItem, ISitefinityCustomTypeSerialization, ILifecycleDataItemGeneric 

    Members and fields are declared like this:
    private string cardType;
    [DataMember]
    [FieldAlias("cardType")]
    public string CardType get ... set...

            

    Each of them has its own manager:
    public class FiltersManager : ContentManagerBase<ProductsDataProvider>, ILifecycleManager

    Provider model is declared like this:
    public abstract class ProductsDataProvider : 
    ContentDataProviderBase, 
    ILanguageDataProvider, 
    IOpenAccessDataProvider

    public override Type[] GetKnownTypes()
           
                if (knownTypes == null)
               
                    knownTypes = new Type[]
                   
                        typeof(ProductItem),
                        typeof(FilterItem),
                        typeof(PersonTypeItem),
                        typeof(QuoteOfTheDayItem),
                        typeof(CardItem)
                    ;
               

                return knownTypes;
           
    //for each item
    public abstract ProductItem CreateProduct();
            public abstract ProductItem CreateProduct(Guid id);
            public abstract ProductItem GetProduct(Guid id);
            public abstract IQueryable<ProductItem> GetProducts();
            public abstract void DeleteProduct(ProductItem product);


    Implementation is declared like this:
    [ContentProviderDecorator(typeof(OpenAccessContentDecorator))]
    public class OpenAccessDataProvider : ProductsDataProvider, IOpenAccessDataProvider

    ...
    public MetadataSource GetMetaDataSource(IDatabaseMappingContext context)
           
                return new ProductsFluentMetadataSource(context);
           
    ...


    ProductsFluentMetadataSource.BuildCustomMappings is
    protected override IList<IOpenAccessFluentMapping> BuildCustomMappings()

         var sitefinityMappings = base.BuildCustomMappings();
         sitefinityMappings.Add(new ProductsFluentMapping(this.Context));
         return sitefinityMappings;



    Mapping is:
    private void MapItem(IList<MappingConfiguration> mappings)
           


                var itemMapping = new MappingConfiguration<ProductItem>();
                itemMapping.HasProperty(p => p.Id).IsIdentity();
                itemMapping.MapType(p => new ).ToTable("Product");
                itemMapping.HasProperty(p => p.ShortDescription);
                itemMapping.HasProperty(p => p.MonthlyCost);
                itemMapping.HasProperty(p => p.OnlineBankMonthlyCost);
                itemMapping.HasProperty(p => p.UpnCost);
                itemMapping.HasProperty(p => p.OnlineBankUpnCost);
                itemMapping.HasProperty(p => p.DirectPaynmentCost);
                itemMapping.HasProperty(p => p.AutomatFee);
                itemMapping.HasProperty(p => p.MaxDailyLimit);
                itemMapping.HasProperty(p => p.MaxEmergencyLimit);
                itemMapping.HasProperty(p => p.MaxFixLimit);
                itemMapping.HasProperty(p => p.HasPersonalAdvisor);
                itemMapping.HasProperty(p => p.HasOnlineBanking);
              
                itemMapping.HasAssociation<Telerik.Sitefinity.Workflow.Model.Tracking.ApprovalTrackingRecordMap>(p => p.ApprovalTrackingRecordMap);
                CommonFluentMapping.MapILifecycleDataItemFields<ProductItem>(itemMapping, this.Context);

                var cardItemMapping = new MappingConfiguration<CardItem>();
                cardItemMapping.HasProperty(p => p.Id).IsIdentity();
                cardItemMapping.MapType(p => new ).ToTable("Card");
                cardItemMapping.HasProperty(p => p.ShortDescription);
                cardItemMapping.HasProperty(p => p.MontlyCost);
                cardItemMapping.HasProperty(p => p.YearlyCost);
                cardItemMapping.HasProperty(p => p.MaxLimit);
                cardItemMapping.HasProperty(p => p.DailyLimit);
                cardItemMapping.HasAssociation<Telerik.Sitefinity.Workflow.Model.Tracking.ApprovalTrackingRecordMap>(p => p.ApprovalTrackingRecordMap);
                CommonFluentMapping.MapILifecycleDataItemFields<CardItem>(cardItemMapping, this.Context);

                
                var quoteOfTheDayItemMapping = new MappingConfiguration<QuoteOfTheDayItem>();
                quoteOfTheDayItemMapping.HasProperty(p => p.Id).IsIdentity();
                quoteOfTheDayItemMapping.MapType(p => new ).ToTable("QuoteOfTheDay");
                quoteOfTheDayItemMapping.HasProperty(p => p.QuoteText);
                quoteOfTheDayItemMapping.HasAssociation<Telerik.Sitefinity.Workflow.Model.Tracking.ApprovalTrackingRecordMap>(p => p.ApprovalTrackingRecordMap);
                CommonFluentMapping.MapILifecycleDataItemFields<QuoteOfTheDayItem>(quoteOfTheDayItemMapping, this.Context);

                var personItemMapping = new MappingConfiguration<PersonTypeItem>();
                personItemMapping.HasProperty(p => p.Id).IsIdentity();
                personItemMapping.MapType(p => new ).ToTable("PersonType");
           //     personItemMapping.HasAssociation<Telerik.Sitefinity.Libraries.Model.Image>(p => p.Image).ToColumn("image_id").IsManaged().IsDependent();

             
                personItemMapping.HasAssociation<Telerik.Sitefinity.Workflow.Model.Tracking.ApprovalTrackingRecordMap>(p => p.ApprovalTrackingRecordMap);
                CommonFluentMapping.MapILifecycleDataItemFields<PersonTypeItem>(personItemMapping, this.Context);

                var filterItemMapping = new MappingConfiguration<FilterItem>();
                filterItemMapping.HasProperty(p => p.Id).IsIdentity();
                filterItemMapping.MapType(p => new ).ToTable("Filter");
           //     filterItemMapping.HasAssociation<Telerik.Sitefinity.Libraries.Model.Image>(p => p.Image).ToColumn("image_id").IsManaged().IsDependent();
                filterItemMapping.HasAssociation<Telerik.Sitefinity.Workflow.Model.Tracking.ApprovalTrackingRecordMap>(p => p.ApprovalTrackingRecordMap);
                CommonFluentMapping.MapILifecycleDataItemFields<FilterItem>(filterItemMapping, this.Context);


                mappings.Add(quoteOfTheDayItemMapping);
                mappings.Add(filterItemMapping);
                mappings.Add(cardItemMapping);
                mappings.Add(personItemMapping);
                mappings.Add(itemMapping);



           


    ProductsConfig:
    [ObjectInfo(typeof(ProductsResources), Title = "ProductsConfigCaption", Description = "ProductsConfigDescription")]
        public class ProductsConfig : ContentModuleConfigBase
       
            protected override void InitializeDefaultProviders(ConfigElementDictionary<string, DataProviderSettings> providers)
           
                providers.Add(new DataProviderSettings(providers)
               
                    Name = "OpenAccessDataProvider",
                    Description = "A provider that stores news data in database using OpenAccess ORM.",
                    ProviderType = typeof(OpenAccessDataProvider),
                    Parameters = new NameValueCollection() "applicationName", "/Products"                
                );
           
    ...


    ModuleInfo:
    public class ModuleInfo : ContentModuleBase
       
    public override void Initialize(Telerik.Sitefinity.Services.ModuleSettings settings)
           
                base.Initialize(settings);
                App.WorkWith()
                    .Module(settings.Name)
               .Initialize()
               .Configuration<ProductsConfig>()
               .Localization<ProductsResources>()
               .WebService<ProductsBackendService>(ProductsBackendService.BaseUrl)
               .WebService<CardBackendService>(CardBackendService.BaseUrl)
               .WebService<FilterBackendService>(FilterBackendService.BaseUrl)
               .WebService<PersonTypeBackendService>(PersonTypeBackendService.BaseUrl)
               .WebService<QuoteOfTheDayBackendService>(QuoteOfTheDayBackendService.BaseUrl);
                
           
    protected override Telerik.Sitefinity.Configuration.ConfigSection GetModuleConfig()
           
                return Config.Get<ProductsConfig>();
           
    public override Type[] Managers
           
                get return new Type[]  
                    typeof(ProductsManager),
                    typeof(CardsManager),
                    typeof(PersonTypesManager),
                    typeof(FiltersManager),
                    typeof(QuoteOfTheDaysManager)
                ;
           
    ...
  • Hello Mitja,

     From the error in your log I suppose that the problem might be connected with your CardsManager (in this case) not being properly implemented - do you have a default constructor defined?. In the code that you pasted, I cannot see the implementation of the Cards Manager class.
    Since it is very difficult to say what the exact issue is without inspecting the whole code and debugging, it would be better if you could open a support ticket and send us your module.

    Regards,
    Svetoslav Petsov
    Telerik
    Do you want to have your say in the Sitefinity development roadmap? Do you want to know when a feature you requested is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  • Hello,

    has this issue been resolved?
    I face the same problem in my custom module.

    Kind Regards,

    Jeroen
  • Not entirely,
    But I managed to add multiple data types into single manager.
    I didn't managed to do that because I didn't find overloaded method for  LifecycleFactory.CreateLifecycle
    Solution is that in manager you define Lifecycle like that:
    public ILifecycleDecorator Lifecycle
            
                get
                
                    return LifecycleFactory.CreateLifecycle(this, this.Copy,
                        new Type[]
                            
                                typeof(ItemType1),
                                typeof(ItemType2),..
                                                             
                            
                        );
                
            

    Instead of:
    public ILifecycleDecorator Lifecycle
            
                get
                
                    return LifecycleFactory.CreateLifecycle<ProductItem>(this, this.Copy);