如何为ASP.NET MVC 5创建dependency injection?
使用ASP.NET Core创建dependency injection非常简单。 文档在这里解释得非常好,这个家伙有一个杀手video来解释它。
但是,我想对我的ASP.NET MVC 5项目做同样的事情。 如何处理ASP.MVC 5的dependency injection?
此外,dependency injection仅限于控制器,还是可以与任何类一起使用?
在ASP.Net MVC中,您可以使用NuGet的.Net Core DI,而不是第三方替代方案之一: –
using Microsoft.Extensions.DependencyInjection
对于MVC Start / Configuration类: –
public void Configuration(IAppBuilder app) { // We will use Dependency Injection for all controllers and other classes, so we'll need a service collection var services = new ServiceCollection(); // configure all of the services required for DI ConfigureServices(services); // Configure authentication ConfigureAuth(app); // Create a new resolver from our own default implementation var resolver = new DefaultDependencyResolver(services.BuildServiceProvider()); // Set the application resolver to our default resolver. This comes from "System.Web.Mvc" //Other services may be added elsewhere through time DependencyResolver.SetResolver(resolver); }
我的项目使用Identity User,我已经取代了OWIN启动配置,而是采用基于服务的方法。 默认的Identity User类使用静态工厂方法来创建实例。 我已将该代码移动到构造函数中并依赖DI来提供适当的注入。 它仍在进行中,但我在这里: –
public void ConfigureServices(IServiceCollection services) { //==================================================== // Create the DB context for the IDENTITY database //==================================================== // Add a database context - this can be instantiated with no parameters services.AddTransient(typeof(ApplicationDbContext)); //==================================================== // ApplicationUserManager //==================================================== // instantiation requires the following instance of the Identity database services.AddTransient(typeof(IUserStore), p => new UserStore (new ApplicationDbContext())); // with the above defined, we can add the user manager class as a type services.AddTransient(typeof(ApplicationUserManager)); //==================================================== // ApplicationSignInManager //==================================================== // instantiation requires two parameters, [ApplicationUserManager] (defined above) and [IAuthenticationManager] services.AddTransient(typeof(Microsoft.Owin.Security.IAuthenticationManager), p => new OwinContext().Authentication); services.AddTransient(typeof(ApplicationSignInManager)); //==================================================== // ApplicationRoleManager //==================================================== // Maps the rolemanager of identity role to the concrete role manager type services.AddTransient, ApplicationRoleManager>(); // Maps the role store role to the implemented type services.AddTransient, RoleStore>(); services.AddTransient(typeof(ApplicationRoleManager)); //==================================================== // Add all controllers as services //==================================================== services.AddControllersAsServices(typeof(Startup).Assembly.GetExportedTypes() .Where(t => !t.IsAbstract && !t.IsGenericTypeDefinition) .Where(t => typeof(IController).IsAssignableFrom(t) || t.Name.EndsWith("Controller", StringComparison.OrdinalIgnoreCase))); }
Account Controller类具有单个构造函数: –
[Authorize] public class AccountController : Controller { private ApplicationSignInManager _signInManager; private ApplicationUserManager _userManager; private RoleManager _roleManager; public AccountController(ApplicationUserManager userManager, ApplicationSignInManager signInManager, RoleManager roleManager) { UserManager = userManager; SignInManager = signInManager; RoleManager = roleManager; }
我建议你使用Autofac ,还有其他类似于unity,ninject,autofac等基准测试的优秀性能。
https://www.palmmedia.de/blog/2011/8/30/ioc-container-benchmark-performance-comparison
这是与MVC的集成(并适用于所有类)
https://docs.autofac.org/en/latest/integration/mvc.html
对于这个答案,我下载了一个WebApi项目的Microsoft示例作为示例的基础,并添加了DI服务,如下所示,
在标准MapHttpRoute配置之后,添加代码以注册您需要的服务
using System; using System.Collections.Generic; using System.Linq; using System.Web.Http; using Microsoft.Extensions.DependencyInjection; using System.Web.Http.Dependencies; using ProductsApp.Controllers; namespace ProductsApp { public static class WebApiConfig { public static void Register(HttpConfiguration config) { // Web API routes config.MapHttpAttributeRoutes(); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); // create the DI services and make the default resolver var services = new ServiceCollection(); services.AddTransient(typeof(DefaultProduct)); services.AddTransient(typeof(ProductsController)); var resolver = new MyDependencyResolver(services.BuildServiceProvider()); config.DependencyResolver = resolver; } } public class DefaultProduct : ProductsApp.Models.Product { public DefaultProduct() { this.Category = "Computing"; this.Id = 999; this.Name = "Direct Injection"; this.Price = 99.99M; } } /// /// Provides the default dependency resolver for the application - based on IDependencyResolver, which hhas just two methods /// public class MyDependencyResolver : IDependencyResolver { protected IServiceProvider _serviceProvider; public MyDependencyResolver(IServiceProvider serviceProvider) { this._serviceProvider = serviceProvider; } public IDependencyScope BeginScope() { return this; } public void Dispose() { } public object GetService(Type serviceType) { return this._serviceProvider.GetService(serviceType); } public IEnumerable
然后我修改了现有的控制器以采用DI类型(注意只有一个ctor)
using ProductsApp.Models; using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Http; using System.Web.Http; namespace ProductsApp.Controllers { public class ProductsController : ApiController { DefaultProduct _dp = null; public ProductsController(DefaultProduct dp) { _dp = dp; // products.Add(dp); } List products = new List () { new Product { Id = 1, Name = "Tomato Soup", Category = "Groceries", Price = 1 }, new Product { Id = 2, Name = "Yo-yo", Category = "Toys", Price = 3.75M }, new Product { Id = 3, Name = "Hammer", Category = "Hardware", Price = 16.99M } }; public IEnumerable GetAllProducts() { return products; } public IHttpActionResult GetProduct(int id) { var product = products.FirstOrDefault((p) => p.Id == id); if (product == null) { return NotFound(); } return Ok(product); } } }
在ASP.NET MVC 5中实现dependency injection的最简单方法是使用Microsoft自己开发的工具,称为Unity
。
您可以在互联网上找到许多有关它的资源,您可以从阅读此处提供的官方文档开始: 使用Unity的开发人员dependency injection指南
此外,dependency injection仅限于控制器,还是可以与任何类一起使用?
它适用于任何项目,在任何项目中,只要您注册与实现相关的接口(如果您想利用IoC模式 ),那么您只需要在构造函数中添加接口实例化。
我的默认依赖关系解析器
/// /// Provides the default dependency resolver for the application - based on IDependencyResolver, which hhas just two methods /// public class DefaultDependencyResolver : IDependencyResolver { /// /// Provides the service that holds the services /// protected IServiceProvider serviceProvider; /// /// Create the service resolver using the service provided (Direct Injection pattern) /// /// public DefaultDependencyResolver(IServiceProvider serviceProvider) { this.serviceProvider = serviceProvider; } /// /// Get a service by type - assume you get the first one encountered /// /// /// public object GetService(Type serviceType) { return this.serviceProvider.GetService(serviceType); } /// /// Get all services of a type /// /// /// public IEnumerable
在此video中,Microsoft MVP使用AutoFac演示MVC5中的dependency injection。 关于如何设置的非常明确的解释:
dependency injectionMVC5演示
源代码可在GitHub上获得
我建议使用Windsor
,通过安装nuget包Castle Windsor MVC Bootstrapper
,然后你可以创建一个实现IWindsorInstaller
的服务,如下所示:
public class ServiceRegister : IWindsorInstaller { public void Install(Castle.Windsor.IWindsorContainer container, Castle.MicroKernel.SubSystems.Configuration.IConfigurationStore store) { SomeTypeRequiredByConstructor context = new SomeTypeRequiredByConstructor (); container.Register( Component .For() .ImplementedBy(). DependsOn(Dependency.OnValue(context))//This is in case your service has parametrize constructoe .LifestyleTransient()); } }
然后在你的控制器里面这样:
public class MyController { IServiceToRegister _serviceToRegister; public MyController (IServiceToRegister serviceToRegister) { _serviceToRegister = serviceToRegister;//Then you can use it inside your controller } }
默认情况下,库将通过在启动时调用ServiceRegister
的install()
来处理向控制器发送正确的服务,因为它实现了IWindsorInstaller
上述就是C#学习教程:如何为ASP.NET MVC 5创建dependency injection?分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1024535.html