Так же отмечу что более подробно об Autofac вы сможете прочитать тут
Для начала мы должны скачать и включить библиотеки Autofac в проект. Для этого я использую NuGet. Введите в консоли:
PM> Install-Package Autofac Устанавливаем сам AutofacPM> Install-Package Autofac.Mvc3 И дополнения к Mvc3Так же вы можете воспользоваться визуальным редактором NuGet, или просто скачать и подключить эти сборки.
Ниже написан код для инициализации Autofac, я постарался включить сюда основные варианты инициализации.
protected void Application_Start() { Trace.TraceInformation("Website initialization started"); AreaRegistration.RegisterAllAreas(); RegisterGlobalFilters(GlobalFilters.Filters); RegisterRoutes(RouteTable.Routes); // Setup IoC container var builder = new ContainerBuilder(); builder.RegisterModule(new ServicesModule()); builder.Register(c => new Entities()).As<IEntities>() .OnActivated(e => { var config = DependencyResolver.Current.GetService<IGlobalSettings>(); e.Instance.RawConnectionString = config.Data.SqlServerConnectionString; }).InstancePerHttpRequest(); builder.RegisterType<LocalizationContext>().PropertiesAutowired().InstancePerHttpRequest(); builder.Register(c => new DefaultGlobalSettings()).As<IGlobalSettings>().SingleInstance(); builder.RegisterGeneric(typeof(MongoRepository<>)) .As(typeof(IMongoRepository<>)).InstancePerHttpRequest(); builder.Register(c => EnvironmentContext()).As<IEnvironmentContext>().InstancePerHttpRequest(); builder.RegisterModule(new AutofacWebTypesModule()); builder.RegisterSource(new ViewRegistrationSource()); builder.RegisterModelBinders(Assembly.GetExecutingAssembly()); builder.RegisterModelBinderProvider(); builder.RegisterFilterProvider(); IContainer container = builder.Build(); DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); Trace.TraceInformation("Website has been successfully initialized"); }
Теперь рассмотрим, что же на самом деле тут произошло.
Регистрируем модуль для Autofac. Это очень полезно для инициализации классов (классы с модификатором доступа internal), которые находятся в отдельной сборке. Нам достаточно оставить ServicesModule в той же сборке, и пользоваться всеми прелестями DI.
builder.RegisterModule(new ServicesModule());
Метод, который должен выполняться для получения необходимого объекта, можно указать следующим образом:
builder.Register(c => EnvironmentContext()).As<IEnvironmentContext>().InstancePerHttpRequest()
То же самое но в виде анонимного делегата.
builder.Register(c => new Entities()).As<IEntities>() .OnActivated(e => { var config = DependencyResolver.Current.GetService<IGlobalSettings>(); e.Instance.RawConnectionString = config.Data.SqlServerConnectionString; }).InstancePerHttpRequest();
Сопоставить клас с интерфейсом можно следующим образом:
builder.Register(c => new DefaultGlobalSettings()).As<IGlobalSettings>().InstancePerHttpRequest();
Для того чтоб зарегистрировать Generic классы воспользуемся следующим кодом:
builder.RegisterGeneric(typeof(MongoRepository<>)) .As(typeof(IMongoRepository<>)).InstancePerHttpRequest();
Для того чтоб инжектировать свойства класса достаточно сделать следующую инициализацию. Отмечу, что DI в конструктор проходит намного быстрее чем на свойство, поэтому использовать подобную инжекцию следует только в крайних случаях.
builder.RegisterType<LocalizationContext>().PropertiesAutowired().InstancePerHttpRequest();
Если заранее известно свойство можно воспользоваться и такой инициализацией:
builder.Register(c => new LocalizationContext { GlobalSettings = c.Resolve<IGlobalSettings>() });
Инициализация классов HttpContextBase, HttpRequestBase, HttpResponseBase, HttpServerUtilityBase, HttpSessionStateBase, HttpApplicationStateBase, HttpBrowserCapabilitiesBase, HttpCachePolicyBase, VirtualPathProvider происходит регистрацией встроенного модуля autofac.
builder.RegisterModule(new AutofacWebTypesModule());
Autofac позволяет проводить инжекцию и в ModelBinder.
builder.RegisterModelBinders(Assembly.GetExecutingAssembly()); builder.RegisterModelBinderProvider();
Инжекция в фильтры (классы производные от ActionFilterAttribute) происходит следующим образом:
builder.RegisterFilterProvider();
Инжекция во View происходит регистрацией следующего модуля.
builder.RegisterSource(new ViewRegistrationSource());
Как вы заметили код сопровождается вызовом:
.InstancePerDependency() — используется по умолчанию, создает новый объект при каждом вызове.
.InstancePerHttpRequest() -один экземпляр на HttpRequest
.SingleInstance() — создает только один экземпляр класса.
.InstancePerLifetimeScope() — создает экземпляр для конкретного LifetimeScope используеться следующим образом:
using (var lifetime = container.BeginLifetimeScope()) { var component = lifetime.Resolve<SomeComponent>(); // component, and any of its disposable dependencies, will // be disposed of when the using block completes }
Получаем экземпляр контейнера.
IContainer container = builder.Build();
Устанавливаем DependencyResolver
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
На этом все. Теперь у вас есть минимальные навыки работы с autofac, и вы можете смело начинать его использовать в своих проекта. Мне было достаточно сложно выделить именно те моменты которые, помогли бы вам освоить Autofac за короткое время. Если я недостаточно осветил какую-либо тему: пожалуйста отпишите это в комментариях.

