How to create dependency injection for ASP.NET MVC 5?

前端 未结 9 1694
挽巷
挽巷 2020-12-23 03:08

Creating Dependency Injection with ASP.NET Core is fairly easy. The documentation explains it very well here and this guy has a killer video to explain it.

However,

相关标签:
9条回答
  • 2020-12-23 04:06

    For this answer I downloaded a Microsoft Example of WebApi project as a basis for the example and added DI services to it as follows,

    • Update the Target Framework to 4.6.1
    • NuGet the DI package :- Microsoft.Extensions.DependencyInjection

    After the standard MapHttpRoute configuration, add code to register which services you need

    using's

    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;
    

    WebApiConfig

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

    DefaultProduct

    public class DefaultProduct : ProductsApp.Models.Product
    {
        public DefaultProduct()
        {
            this.Category = "Computing";
            this.Id = 999;
            this.Name = "Direct Injection";
            this.Price = 99.99M;
        }
    }
    

    MyDependencyResolver

    /// <summary>
    /// Provides the default dependency resolver for the application - based on IDependencyResolver, which hhas just two methods.
    /// This is combined dependency resolver for MVC and WebAPI usage.
    /// </summary>
    public class MyDependencyResolver : System.Web.Mvc.IDependencyResolver, System.Web.Http.Dependencies.IDependencyResolver 
    {
        protected IServiceProvider serviceProvider;
        protected IServiceScope scope = null;
    
        public MyDependencyResolver(IServiceProvider serviceProvider) 
        {
            this.serviceProvider = serviceProvider;
        }
    
        public MyDependencyResolver(IServiceScope scope) 
        {
            this.scope = scope;
            this.serviceProvider = scope.ServiceProvider;
        }
    
        public IDependencyScope BeginScope() 
        {
            return new MyDependencyResolver(serviceProvider.CreateScope());
        }
    
        public void Dispose() 
        {
            Dispose(true);
        }
    
        protected virtual void Dispose(bool disposing) 
        {
            scope?.Dispose();
        }
    
        public object GetService(Type serviceType) 
        {
            return this.serviceProvider.GetService(serviceType);
        }
    
        public IEnumerable<object> GetServices(Type serviceType) 
        {
            return this.serviceProvider.GetServices(serviceType);
        }
    }
    

    ServiceProviderExtensions

    public static class ServiceProviderExtensions
    {
        public static IServiceCollection AddControllersAsServices(this IServiceCollection services, IEnumerable<Type> serviceTypes)
        {
            foreach (var type in serviceTypes)
            {
                services.AddTransient(type);
            }
    
            return services;
        }
    }
    

    I then amended the existing controller to take the DI type (note there is just the one 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<Product> products = new List<Product>()
            {
                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<Product> GetAllProducts()
            {
                return products;
            }
    
            public IHttpActionResult GetProduct(int id)
            {
                var product = products.FirstOrDefault((p) => p.Id == id);
                if (product == null)
                {
                    return NotFound();
                }
                return Ok(product);
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-23 04:06

    I recommend you use Autofac, there are anothers fwk like unity, ninject, the benchmarks autofac has excelent perfomance.

    http://www.palmmedia.de/blog/2011/8/30/ioc-container-benchmark-performance-comparison

    Here is the integration with MVC (and works with all class)

    http://docs.autofac.org/en/latest/integration/mvc.html

    0 讨论(0)
  • 2020-12-23 04:09

    From here https://scottdorman.blog/2016/03/17/integrating-asp-net-core-dependency-injection-in-mvc-4/

    this line saved me.

        services.AddControllersAsServices(typeof(Startup).Assembly.GetExportedTypes()
          .Where(t => !t.IsAbstract && !t.IsGenericTypeDefinition)
          .Where(t => typeof(IController).IsAssignableFrom(t) 
           || t.Name.EndsWith("Controller", StringComparison.OrdinalIgnoreCase)));
    
    0 讨论(0)
提交回复
热议问题