有没有人成功地使用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);
                }
            }

它似乎从未在我的unity文件中查找以解决依赖关系,我会遇到如下错误:

try 创建类型为的控制器时出错 ‘PersonalShopper.Services.WebApi.Controllers.ShoppingListController’. 确保控制器具有无参数的公共构造函数.

控制器看起来像:

public class ShoppingListController : System.Web.Http.ApiController
    {
        private Repositories.IProductListRepository _ProductListRepository;


        public ShoppingListController(Repositories.IUserRepository userRepository,
            Repositories.IProductListRepository productListRepository)
        {
            _ProductListRepository = productListRepository;
        }
}

我的unity文件如下所示:

<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版本中,控制器工厂会发现需要解决依赖关系.

我的控制器工厂似乎从来没有人打过电话.

推荐答案

我想通了.

对于ApiControllers,MVC4使用System.Web.Http.Dispatcher.IHttpControllerFactorySystem.Web.Http.Dispatcher.IHttpControllerActivator来创建控制器.如果没有静态方法来注册它们的实现;解决这些问题后,mvc框架会在依赖项解析器中查找实现,如果找不到,则使用默认实现.

通过执行以下操作,我获得了控制器依赖关系的统一解析:

创建了UnityHttpController激活程序:

public class UnityHttpControllerActivator : IHttpControllerActivator
{
    private IUnityContainer _container;

    public UnityHttpControllerActivator(IUnityContainer container)
    {
        _container = container;
    }

    public IHttpController Create(HttpControllerContext controllerContext, Type controllerType)
    {
        return (IHttpController)_container.Resolve(controllerType);
    }
}

将控制器激活器注册为unity容器本身中的实现:

protected void Application_Start()
{
    // code intentionally omitted

    IUnityContainer container = BuildUnityContainer();
    container.RegisterInstance<IHttpControllerActivator>(new UnityHttpControllerActivator(container));

    ServiceResolver.SetResolver(t =>
       {
         // rest of code is the same as in question above, and is omitted.
       });
}

.net相关问答推荐

找不到包Microsoft.VisualStudio.Azure.Containers.Tools.Targets

为什么$NULL在ForEach-Object{}和Foreach()中的行为不同?

将多行参数传递给Power Shell中的DotNet Pack命令

无法在Ubuntu 22.04.3上运行带有Rider 2023和DotNet-8.0的项目

.NET模拟具有泛型返回类型的方法

PowerShell 5.1和7在使用证书时的区别

是否必须使用 Visual Studio 预览才能使用 MAUI?

当 Func 委托需要接口作为参数时,它是如何工作的?

如何创建 LINQ to SQL 事务?

将客户端证书添加到 .NET Core HttpClient

使用 .NET 在 Windows 中创建弹出式 toastr 通知

返回 IQueryable 或不返回 IQueryable

为什么要判断这个!= null?

HashSet 是否保留插入顺序?

C# 的 Actors 有什么好的实现吗?

如果需要,将方案添加到 URL

覆盖方法上的 C# 可选参数

获取磁盘上文件的大小

清除文件内容

将控制台输出镜像到文件