AutoFac a récemment été mis à jour pour MVC 5.1 mais au moment de la rédaction, je trouve que la documentation fait défaut (en particulier pour un exemple simple).
Je voudrais injecter des dépendances dans les contrôleurs MVC et enregistrer mes propres implémentations, par exemple e-mail (envoi réel vs impression vers la fenêtre de sortie) comme exemple de base.
Je ne sais pas si je manque une bonne ressource pour cela et je suis légèrement inquiet car, car il utilise la spécification OWIN, l'implémentation peut différer pour MVC5.1 (l'identité ASP.NET utilise OWIN et il existe des attributs spéciaux utilisés pour instancier correctement OWIN), il faut donc vérifier que je fais les choses correctement.
J'ai un exemple de travail avec le code d'installation ci-dessous - est-ce correct et une bonne pratique pour une application web MVC5.1 standard?
Question bonus: dois-je ajouter InstancePerHttpRequest à la ligne RegisterControllers? c'est-à-dire builder.RegisterControllers (typeof (MvcApplication) .Assembly) .InstancePerHttpRequest ();
(Remarque: je vois les exemples sur GitHub d'Autofac mais je ne trouve pas d'exemple simple approprié à 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));
}
Et mon contrôleur:
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();
}
}
Merci!
Voici ce que j'ai - commentaires bienvenus!
Global.asax.cs:
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
// Register Inversion of Control dependencies
IoCConfig.RegisterDependencies();
// Typical MVC setup
// ....
}
}
Dossier 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
}
}
Ensuite, vous pouvez enregistrer des modules comme bon vous semble, ce qui est vraiment génial si vous avez une application modulaire et que vous ne savez pas ce que vous allez inclure dans votre projet. Vous pouvez nuget configurer votre projet et aucune intervention manuelle requise (je le souhaite!) ....
public class RegisterApplicationIoC : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<EmailSenderToDebug>()
.As<IEmailSender>()
.InstancePerHttpRequest();
}
}