22

AutoFac недавно был обновлен для MVC 5.1, но на момент написания я обнаружил, что документации не хватает (особенно для простого примера).Как правильно зарегистрировать AutoFac на базовом веб-сайте MVC5.1?

Я хотел бы добавить зависимости в контроллеры MVC и зарегистрировать свои собственные реализации, например. e-mail (фактическая отправка и печать в окно вывода) в качестве базового примера.

Я не знаю, не хватает ли я для этого хорошего ресурса, и я слегка обеспокоен тем, что, поскольку он использует спецификацию OWIN, реализация может отличаться для MVC5.1 (идентификатор ASP.NET использует OWIN, и существует некоторые специальные атрибуты, используемые для правильного создания OWIN), поэтому вам нужно проверить, что я правильно понимаю.

У меня есть рабочий пример с приведенным ниже установочным кодом - это правильная и эффективная практика для стандартного веб-приложения MVC5.1?

Вопрос с бонусом: мне нужно добавить экземпляр InstancePerHttpRequest в строку RegisterControllers? i.e. builder.RegisterControllers (typeof (MvcApplication) .Сборка) .InstancePerHttpRequest();

(Примечание. Я вижу примеры на GitHub из Autofac, но не может найти простой пример, соответствующий MVC5.1)

public static void RegisterDependencies() 
{ 
    // Register MVC-related dependencies 
    var builder = new ContainerBuilder(); 
    builder.RegisterControllers(typeof(MvcApplication).Assembly); 
    builder.RegisterModelBinders(typeof(MvcApplication).Assembly); 
    builder.RegisterModule<AutofacWebTypesModule>(); 

    // Register e-mail service 
    builder.RegisterType<EmailSenderToDebug>().As<IEmailSender>().InstancePerHttpRequest(); 

    builder.RegisterModelBinderProvider(); 

    // Set the MVC dependency resolver to use Autofac 
    var container = builder.Build(); 
    DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); 
} 

И мой контроллер:

public class HomeController : Controller 
{ 

    public IEmailSender _email { get; set; } 

    public HomeController(IEmailSender es) 
    { 
     this._email = es; 
    } 
    // 
    // GET: /Home/ 
    public ActionResult Index() 
    { 

     Email e = new Email(); 
     e.To(new MailAddress("[email protected]", "mr. something")); 
     e.Subject("test"); 
     e.Message("hello world"); 
     e.From(new MailAddress("[email protected]", "mr. else")); 
     this._email.SendEmail(e); 
     return View(); 
    } 
} 

Спасибо!

ответ

37

Вот что у меня есть - обратная связь приветствуется!

Global.asax.cs:

public class MvcApplication : System.Web.HttpApplication 
{ 
    protected void Application_Start() 
    { 
     // Register Inversion of Control dependencies 
     IoCConfig.RegisterDependencies(); 

     // Typical MVC setup 
     // .... 
    } 
} 

App_Start Папка:

public class IoCConfig 
{ 

    /// <summary> 
    /// For more info see 
    /// :https://code.google.com/p/autofac/wiki/MvcIntegration (mvc4 instructions) 
    /// </summary> 
    public static void RegisterDependencies() 
    { 
     #region Create the builder 
     var builder = new ContainerBuilder(); 
     #endregion 

     #region Setup a common pattern 
     // placed here before RegisterControllers as last one wins 
     builder.RegisterAssemblyTypes() 
       .Where(t => t.Name.EndsWith("Repository")) 
       .AsImplementedInterfaces() 
       .InstancePerHttpRequest(); 
     builder.RegisterAssemblyTypes() 
       .Where(t => t.Name.EndsWith("Service")) 
       .AsImplementedInterfaces() 
       .InstancePerHttpRequest(); 
     #endregion 

     #region Register all controllers for the assembly 
     // Note that ASP.NET MVC requests controllers by their concrete types, 
     // so registering them As<IController>() is incorrect. 
     // Also, if you register controllers manually and choose to specify 
     // lifetimes, you must register them as InstancePerDependency() or 
     // InstancePerHttpRequest() - ASP.NET MVC will throw an exception if 
     // you try to reuse a controller instance for multiple requests. 
     builder.RegisterControllers(typeof(MvcApplication).Assembly) 
       .InstancePerHttpRequest(); 

     #endregion 

     #region Register modules 
     builder.RegisterAssemblyModules(typeof(MvcApplication).Assembly); 
     #endregion 

     #region Model binder providers - excluded - not sure if need 
     //builder.RegisterModelBinders(Assembly.GetExecutingAssembly()); 
     //builder.RegisterModelBinderProvider(); 
     #endregion 

     #region Inject HTTP Abstractions 
     /* 
     The MVC Integration includes an Autofac module that will add HTTP request 
     lifetime scoped registrations for the HTTP abstraction classes. The 
     following abstract classes are included: 
     -- HttpContextBase 
     -- HttpRequestBase 
     -- HttpResponseBase 
     -- HttpServerUtilityBase 
     -- HttpSessionStateBase 
     -- HttpApplicationStateBase 
     -- HttpBrowserCapabilitiesBase 
     -- HttpCachePolicyBase 
     -- VirtualPathProvider 

     To use these abstractions add the AutofacWebTypesModule to the container 
     using the standard RegisterModule method. 
     */ 
     builder.RegisterModule<AutofacWebTypesModule>(); 

     #endregion 

     #region Set the MVC dependency resolver to use Autofac 
     var container = builder.Build(); 
     DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); 
     #endregion 

    } 

} 

Затем вы можете зарегистрировать модули по своему усмотрению, которые действительно здорово, если у вас есть приложение, и на модульную систему вы не» Знаете, что вы собираетесь включить в свой проект. Вы можете NuGet настроить ваш проект и без ручного вмешательства требуется (я хочу!) ....

public class RegisterApplicationIoC : Module 
{ 
    protected override void Load(ContainerBuilder builder) 
    { 
     builder.RegisterType<EmailSenderToDebug>() 
       .As<IEmailSender>() 
       .InstancePerHttpRequest(); 
    } 
} 
+20

'InstancePerHttpRequest' осуждался для' AutoFac 3.4.0' и '4.0.0' замена быть' InstancePerRequest' , См. [Здесь] (https://github.com/autofac/Autofac/commit/78e3ff71286fab6185ea8a89ae622825afa741a5) – jbaum012

+0

Добавление 'IoCConfig.RegisterDependencies();' to 'Global.asax' просит меня добавить соответствующее пространство имен. При этом я получаю следующую ошибку: «Ссылка на« Bootstrapper »не может быть добавлена. Добавление этого проекта в качестве ссылки вызовет циклическую зависимость. «Я знаю **, почему ** этой ошибки. Я хочу знать, как ** разрешить это? – barnes

+0

Мне удалось запустить его после перемещения файла 'IocConfig.cs' в папку« App_Start ». Проблема из моего последнего комментария также была решена. Теперь я хочу знать, как ** поддерживать структуру папок? Каковы стандарты создания структуры папки/проекта при использовании autofac? Есть ли способ разместить файл 'IocConfig' в другой папке? Просьба предоставить ссылки (если таковые имеются). – barnes

Смежные вопросы