using System; using LightInject; using Umbraco.Core.Cache; using Umbraco.Core.IO; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.Mappers; using Umbraco.Core.Persistence.Repositories; using Umbraco.Core.Persistence.UnitOfWork; using Umbraco.Core.Plugins; namespace Umbraco.Core.DI { /// /// Sets the IoC container for the umbraco data layer/repositories/sql/database/etc... /// public sealed class RepositoryCompositionRoot : ICompositionRoot { public const string DisabledCache = "DisabledCache"; public void Compose(IServiceRegistry container) { // register database context container.RegisterSingleton(); // register IUnitOfWork providers container.RegisterSingleton(); container.RegisterSingleton(); // register repository factory container.RegisterSingleton(); // register file systems container.RegisterSingleton(factory => new PhysicalFileSystem(SystemDirectories.Scripts), "ScriptFileSystem"); container.RegisterSingleton(factory => new PhysicalFileSystem(SystemDirectories.MvcViews + "/Partials/"), "PartialViewFileSystem"); container.RegisterSingleton(factory => new PhysicalFileSystem(SystemDirectories.MvcViews + "/MacroPartials/"), "PartialViewMacroFileSystem"); container.RegisterSingleton(factory => new PhysicalFileSystem(SystemDirectories.Css), "StylesheetFileSystem"); container.RegisterSingleton(factory => new PhysicalFileSystem(SystemDirectories.Masterpages), "MasterpageFileSystem"); container.RegisterSingleton(factory => new PhysicalFileSystem(SystemDirectories.MvcViews), "ViewFileSystem"); // register cache helpers // the main cache helper is registered by CoreBootManager and is used by most repositories // the disabled one is used by those repositories that have an annotated ctor parameter container.RegisterSingleton(factory => CacheHelper.CreateDisabledCacheHelper(), DisabledCache); // resolve ctor dependency from GetInstance() runtimeArguments, if possible - 'factory' is // the container, 'info' describes the ctor argument, and 'args' contains the args that // were passed to GetInstance() - use first arg if it is the right type, // // for IDatabaseUnitOfWork container.RegisterConstructorDependency((factory, info, args) => args.Length > 0 ? args[0] as IDatabaseUnitOfWork : null); // for IUnitOfWork container.RegisterConstructorDependency((factory, info, args) => args.Length > 0 ? args[0] as IUnitOfWork : null); // register repositories // repos depend on various things, and a IDatabaseUnitOfWork (registered above) // some repositories have an annotated ctor parameter to pick the right cache helper // repositories container.Register(); container.Register(); container.Register(); container.Register(); container.Register(); container.Register(); container.Register(); container.Register(); container.Register(); container.Register(); container.Register(); container.Register(); container.Register(); container.Register(); container.Register(); container.Register(); container.Register(); container.Register(); container.Register(); container.Register(); container.Register(); container.Register(); container.Register(); container.Register(); container.Register(); container.Register(); container.Register(); container.Register(); container.Register(); container.Register(); container.Register(); // repositories that depend on a filesystem // these have an annotated ctor parameter to pick the right file system container.Register(); container.Register(); container.Register(); container.Register(); // collection builders require a full IServiceContainer because they need to // be able to both register stuff, and get stuff - but ICompositionRoot gives // us an IServiceRegistry - which *is* a full container - so, casting - bit // awkward but it works var serviceContainer = container as IServiceContainer; if (serviceContainer == null) throw new Exception("Container is not IServiceContainer."); } } }