Создание и внедрение зависимостей с ASP.NET ядро довольно легко. Документация объясняет это очень хорошо здесь и это [убийца видео][2], чтобы объяснить это.
Однако, я хочу сделать то же самое с моим проектом ASP.NET в MVC 5. Как справиться с внедрения зависимостей с ASP.В MVC 5?
Кроме того, внедрение зависимостей ограничивается только контроллеры или она может работать с любым классом?
В ASP.Net в MVC можно использовать .Чистая ядро Ди из NuGet, а не один из сторонних альтернатив:-
using Microsoft.Extensions.DependencyInjection
Для MVC в начало класс/конфигурация:-
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);
}
Мой проект использует идентификатор пользователя и я'вэ заменены OWIN в запуск конфигурации выполните сервис-ориентированного подхода вместо. Идентификация классов пользователей по умолчанию использовать статические методы фабрики для создания экземпляров. Я'вэ переехал этот код в конструкторах и опирался на Ди, чтобы обеспечить соответствующие инъекции. Он по-прежнему работать в прогресс, но вот где я нахожусь по адресу:-
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<ApplicationUser>), p => new UserStore<ApplicationUser>(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<RoleManager<IdentityRole>, ApplicationRoleManager>();
// Maps the role store role to the implemented type
services.AddTransient<IRoleStore<IdentityRole, string>, RoleStore<IdentityRole>>();
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)));
}
Контроллер учетной записи класс имеет один конструктор:-
[Authorize]
public class AccountController : Controller
{
private ApplicationSignInManager _signInManager;
private ApplicationUserManager _userManager;
private RoleManager<IdentityRole> _roleManager;
public AccountController(ApplicationUserManager userManager, ApplicationSignInManager signInManager, RoleManager<IdentityRole> roleManager)
{
UserManager = userManager;
SignInManager = signInManager;
RoleManager = roleManager;
}
За этот ответ я скачал пример Майкрософт проект веб-API в качестве основы для примера и добавил Ди услуги следующим образом:
После стандартной конфигурации 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;
}
}
/// <summary>
/// Provides the default dependency resolver for the application - based on IDependencyResolver, which hhas just two methods
/// </summary>
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<object> GetServices(Type serviceType)
{
return this._serviceProvider.GetServices(serviceType);
}
public void AddService()
{
}
}
public static class ServiceProviderExtensions
{
public static IServiceCollection AddControllersAsServices(this IServiceCollection services, IEnumerable<Type> serviceTypes)
{
foreach (var type in serviceTypes)
{
services.AddTransient(type);
}
return services;
}
}
}
Затем я внес изменения в существующий контроллер, чтобы взять Ди типа (Внимание, есть только один конструктор)
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);
}
}
}
Я рекомендую вам использовать Autofac, есть и другие fwk нравится Unity, ninject, autofac ориентиры и низкая производительность.
http://www.palmmedia.de/blog/2011/8/30/ioc-container-benchmark-performance-comparison
Вот это интеграция с MVC (и работает со всем классом)
Самый простой способ реализует внедрение зависимостей в ASP.NET в MVC 5 заключается в использовании инструмент, разработанный самой Microsoft, под названием "Единство".
Вы можете найти много ресурсов в интернете о нем, и вы можете начать с чтения официальной документации здесь: разработчик'ы руководство для внедрения зависимостей с помощью Unity
кроме того, внедрение зависимостей ограничивается только контроллеры или она может работать с любым классом?
Она работает с любым классом, в любом проекте, так долго, как вы зарегистрируетесь интерфейса, связанные с реализацией (если вы хотите взять прибыль МОК шаблон), все, что вам нужно сделать, это добавить интерфейс инициализацию в конструкторе.
Мой Решатель Зависимостей По Умолчанию
/// <summary>
/// Provides the default dependency resolver for the application - based on IDependencyResolver, which hhas just two methods
/// </summary>
public class DefaultDependencyResolver : IDependencyResolver
{
/// <summary>
/// Provides the service that holds the services
/// </summary>
protected IServiceProvider serviceProvider;
/// <summary>
/// Create the service resolver using the service provided (Direct Injection pattern)
/// </summary>
/// <param name="serviceProvider"></param>
public DefaultDependencyResolver(IServiceProvider serviceProvider)
{
this.serviceProvider = serviceProvider;
}
/// <summary>
/// Get a service by type - assume you get the first one encountered
/// </summary>
/// <param name="serviceType"></param>
/// <returns></returns>
public object GetService(Type serviceType)
{
return this.serviceProvider.GetService(serviceType);
}
/// <summary>
/// Get all services of a type
/// </summary>
/// <param name="serviceType"></param>
/// <returns></returns>
public IEnumerable<object> GetServices(Type serviceType)
{
return this.serviceProvider.GetServices(serviceType);
}
}
В данном видео специалист MVP по Microsoft Демос зависимостей инъекции в MVC5 с AutoFac. Очень четкое объяснение о том, как его настроить:
Зависимость MVC5 инъекции демо
Исходный код доступен на на GitHub
Отсюда https://scottdorman.blog/2016/03/17/integrating-asp-net-core-dependency-injection-in-mvc-4/
эта строка меня спасла.
услуги.AddControllersAsServices(для вызова typeof(запуск).Сборка.GetExportedTypes() .Где(Т => !Т.IsAbstract &&усилителя; !Т.IsGenericTypeDefinition) .Где(Т => typeof на(IController).IsAssignableFrom(Т) || Т.Имя.Метода endswith (на"контроллер" и, значение stringcomparison.OrdinalIgnoreCase)));
Я рекомендую использовать "Виндзор", установив пакет NuGet замок Виндзор в MVC загрузчика, затем можно создать сервис, который реализует 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<IServiceToRegister>()
.ImplementedBy<ServiceToRegister>().
DependsOn(Dependency.OnValue<SomeTypeRequiredByConstructor>(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при запуске, потому что он реализует
IWindsorInstaller`