mvc c# dependency-injection asp.net-mvc-5 autofac asp.net-mvc-5.1

c# - ¿Cómo registro correctamente AutoFac en un sitio web MVC5.1 básico?



autofac github (1)

Esto es lo que tengo: ¡bienvenidos tus comentarios!

Global.asax.cs:

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

Carpeta 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 } }

Luego puede registrar módulos como mejor le parezca, lo que es realmente bueno si tiene una aplicación modularizada y no sabe qué va a incluir en su proyecto. Puede configurar su proyecto sin necesidad de intervención manual (¡lo deseo!) ....

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

AutoFac se ha actualizado recientemente para MVC 5.1, pero en el momento de redactar este artículo me parece que falta documentación (especialmente para un ejemplo sencillo).

Me gustaría inyectar dependencias en los Controladores MVC y registrar mis propias implementaciones para, por ejemplo, correo electrónico (envío real frente a impresión en la ventana de salida) como un ejemplo básico.

No sé si me falta un buen recurso para esto y me preocupa un poco que, debido a que usa la especificación OWIN, la implementación puede diferir para MVC5.1 (la identidad de ASP.NET usa OWIN y se usan algunos atributos especiales) para crear correctamente una instancia de OWIN), por lo que debo comprobar que estoy haciendo las cosas bien.

Tengo un ejemplo de trabajo con el siguiente código de configuración. ¿Es esta una práctica correcta y correcta para una aplicación web MVC5.1 estándar?

Pregunta extra: ¿necesito agregar InstancePerHttpRequest a la línea RegisterControllers? es decir, builder.RegisterControllers (typeof (MvcApplication) .Assembly) .InstancePerHttpRequest ();

(Nota: Veo los ejemplos en GitHub de Autofac pero no puedo encontrar un ejemplo simple apropiado para 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)); }

Y mi controlador:

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(); } }

¡Gracias!