Кто-нибудь имел успех, используя контейнер IoC для внедрения зависимостей в контроллеры ASP.NET WebAPI? Кажется, я не могу заставить его работать.
Вот чем я сейчас занимаюсь.
По моему global.ascx.cs
:
public static void RegisterRoutes(RouteCollection routes)
{
// code intentionally omitted
}
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
IUnityContainer container = BuildUnityContainer();
System.Web.Http.GlobalConfiguration.Configuration.ServiceResolver.SetResolver(
t =>
{
try
{
return container.Resolve(t);
}
catch (ResolutionFailedException)
{
return null;
}
},
t =>
{
try
{
return container.ResolveAll(t);
}
catch (ResolutionFailedException)
{
return new System.Collections.Generic.List<object>();
}
});
System.Web.Mvc.ControllerBuilder.Current.SetControllerFactory(new UnityControllerFactory(container));
BundleTable.Bundles.RegisterTemplateBundles();
}
private static IUnityContainer BuildUnityContainer()
{
var container = new UnityContainer().LoadConfiguration();
return container;
}
Моя фабрика контроллеров:
public class UnityControllerFactory : DefaultControllerFactory
{
private IUnityContainer _container;
public UnityControllerFactory(IUnityContainer container)
{
_container = container;
}
public override IController CreateController(System.Web.Routing.RequestContext requestContext,
string controllerName)
{
Type controllerType = base.GetControllerType(requestContext, controllerName);
return (IController)_container.Resolve(controllerType);
}
}
Кажется, он никогда не заглядывает в мой файл единства для разрешения зависимостей, и я получаю сообщение об ошибке:
Произошла ошибка при попытке создать контроллер типа PersonalShopper.Services.WebApi.Controllers.ShoppingListController. Убедитесь, что в контроллере есть открытый конструктор без параметров.
в System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create (HttpControllerContext controllerContext, Type controllerType) в System.Web.Http.Dispatcher.DefaultHttpControllerFactory.CreateInstance (HttpControllerFactory.CreateInstance (HttpControllerFactory. (HttpControllerContext controllerContext, String controllerName) в System.Web.Http.Dispatcher.HttpControllerDispatcher.SendAsyncInternal (запрос HttpRequestMessage, CancellationToken cancellationToken) в System.Web.Http.Dispatcher.Http.DispatcherControllerDispatcher.HttpRequestMessage request, CancellationToken cancellationToken.
Контроллер выглядит так:
public class ShoppingListController : System.Web.Http.ApiController
{
private Repositories.IProductListRepository _ProductListRepository;
public ShoppingListController(Repositories.IUserRepository userRepository,
Repositories.IProductListRepository productListRepository)
{
_ProductListRepository = productListRepository;
}
}
Мой файл единства выглядит так:
<unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
<container>
<register type="PersonalShopper.Repositories.IProductListRepository, PersonalShopper.Repositories" mapTo="PersonalShopper.Implementations.MongoRepositories.ProductListRepository, PersonalShopper.Implementations" />
</container>
</unity>
Обратите внимание, что у меня нет регистрации для самого контроллера, потому что в предыдущих версиях mvc фабрика контроллеров определяла, что зависимости необходимо разрешить.
Похоже, моя фабрика контроллеров никогда не вызывается.
источник
GlobalConfiguration.Configuration.ServiceResolver.SetResolver()
?Здесь есть лучшее решение, которое работает правильно
http://www.asp.net/web-api/overview/extensibility/using-the-web-api-dependency-resolver
источник
Возможно, вы захотите взглянуть на пакет NuGet Unity.WebApi, который рассортирует все это, а также обслуживает компоненты IDisposable.
видеть
http://nuget.org/packages/Unity.WebAPI
или же
http://www.devtrends.co.uk/blog/introduction-the-unity.webapi-nuget-package
источник
UnityResolver
.Microsoft создала для этого пакет.
Выполните следующую команду из консоли диспетчера пакетов.
установочный пакет Unity.AspNet.WebApi
Если у вас уже установлен Unity, он спросит, хотите ли вы перезаписать App_Start \ UnityConfig.cs. Ответьте нет и продолжайте.
Нет необходимости менять какой-либо другой код, и DI (с единицей) будет работать.
источник
У меня была такая же ошибка, и я пару часов искал в Интернете решения. В конце концов выяснилось, что мне нужно зарегистрировать Unity ДО того, как я вызвал WebApiConfig.Register. Мой global.asax теперь выглядит как
public class WebApiApplication : System.Web.HttpApplication { protected void Application_Start() { UnityConfig.RegisterComponents(); AreaRegistration.RegisterAllAreas(); GlobalConfiguration.Configure(WebApiConfig.Register); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); } }
Для меня это решило проблему, заключающуюся в том, что Unity не может разрешить зависимости в моих контроллерах.
источник
В недавнем RC я обнаружил, что метода SetResolver больше нет. Чтобы включить IoC для контроллера и webapi, я использую Unity.WebApi (NuGet) и следующий код:
public static class Bootstrapper { public static void Initialise() { var container = BuildUnityContainer(); GlobalConfiguration.Configuration.DependencyResolver = new Unity.WebApi.UnityDependencyResolver(container); ControllerBuilder.Current.SetControllerFactory(new DefaultControllerFactory(new ControllerActivator())); } private static IUnityContainer BuildUnityContainer() { var container = new UnityContainer(); container.Configure(c => c.Scan(scan => { scan.AssembliesInBaseDirectory(); scan.With<UnityConfiguration.FirstInterfaceConvention>().IgnoreInterfacesOnBaseTypes(); })); return container; } } public class ControllerActivator : IControllerActivator { IController IControllerActivator.Create(RequestContext requestContext, Type controllerType) { return GlobalConfiguration.Configuration.DependencyResolver.GetService(controllerType) as IController; } }
Я также использую UnityConfiguration (также из NuGet) для магии IoC. ;)
источник
После прочтения ответов мне все еще пришлось много копаться, чтобы добраться до этой ошибки, так что вот она для пользы коллег: это все, что вам нужно сделать в ASP.NET 4 Web API RC (как 8 августа '13):
И вот, вы получаете зависимости, внедряемые в ваш конструктор, без лишней строчки кода!
ПРИМЕЧАНИЕ: я получил эту информацию из одного из комментариев автора в ЭТОМ блоге.
источник
Краткое описание веб-API ASP.NET 2.
Установить
Unity
из NuGet.Создайте новый класс с именем
UnityResolver
:using Microsoft.Practices.Unity; using System; using System.Collections.Generic; using System.Web.Http.Dependencies; public class UnityResolver : IDependencyResolver { protected IUnityContainer container; public UnityResolver(IUnityContainer container) { if (container == null) { throw new ArgumentNullException("container"); } this.container = container; } public object GetService(Type serviceType) { try { return container.Resolve(serviceType); } catch (ResolutionFailedException) { return null; } } public IEnumerable<object> GetServices(Type serviceType) { try { return container.ResolveAll(serviceType); } catch (ResolutionFailedException) { return new List<object>(); } } public IDependencyScope BeginScope() { var child = container.CreateChildContainer(); return new UnityResolver(child); } public void Dispose() { Dispose(true); } protected virtual void Dispose(bool disposing) { container.Dispose(); } }
Создайте новый класс с именем
UnityConfig
:public static class UnityConfig { public static void ConfigureUnity(HttpConfiguration config) { var container = new UnityContainer(); container.RegisterType<ISomethingRepository, SomethingRepository>(); config.DependencyResolver = new UnityResolver(container); } }
Отредактируйте App_Start -> WebApiConfig.cs
public static void Register(HttpConfiguration config) { UnityConfig.ConfigureUnity(config); ...
Теперь будет работать.
Исходный код, но немного измененный: https://docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/dependency-injection
источник
У меня было такое же исключение, и в моем случае у меня был конфликт между двоичными файлами MVC3 и MVC4. Это препятствовало правильной регистрации моих контроллеров в моем контейнере IOC. Проверьте свой web.config и убедитесь, что он указывает на правильные версии MVC.
источник
Эта проблема возникает из-за регистрации контроллеров в Unity. Я решил это, используя регистрацию по соглашению, как показано ниже. Пожалуйста, отфильтруйте любые дополнительные типы по мере необходимости.
IUnityContainer container = new UnityContainer(); // Do not register ApiControllers with Unity. List<Type> typesOtherThanApiControllers = AllClasses.FromLoadedAssemblies() .Where(type => (null != type.BaseType) && (type.BaseType != typeof (ApiController))).ToList(); container.RegisterTypes( typesOtherThanApiControllers, WithMappings.FromMatchingInterface, WithName.Default, WithLifetime.ContainerControlled);
Также в приведенном выше примере используется
AllClasses.FromLoadedAssemblies()
. Если вы просматриваете загрузку сборок из базового пути, это может не работать должным образом в проекте веб-API с использованием Unity. Пожалуйста, взгляните на мой ответ на другой вопрос, связанный с этим. https://stackoverflow.com/a/26624602/1350747источник
У меня была такая же проблема при использовании пакета NuGet Unity.WebAPI. Проблема заключалась в том, что пакет никогда не добавлял вызов
UnityConfig.RegisterComponents()
в мой Global.asax.Global.asax.cs должен выглядеть так:
public class WebApiApplication : System.Web.HttpApplication { protected void Application_Start() { UnityConfig.RegisterComponents(); ... } }
источник