首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >web api中的统一接口映射异常

web api中的统一接口映射异常
EN

Stack Overflow用户
提问于 2016-09-05 04:00:50
回答 1查看 770关注 0票数 2

在调试代码时,我会得到此异常:

代码语言:javascript
复制
Resolution of the dependency failed, type = "Aqueduct.Interfaces.IMasterDataClient", name = "MDS".
Exception occurred while: while resolving.
Exception is: InvalidOperationException - The current type,
Aqueduct.Interfaces.IMasterDataClient, is an interface and cannot be constructed. Are you missing a type mapping?

在出现异常时,容器代码是:

Resolving Aqueduct.Interfaces.IMasterDataClient,MDS

Unity.config:

代码语言:javascript
复制
public static class UnityConfig
{
    public static void RegisterComponents()
    {
        var container = new UnityContainer();
        IUnityContainer myContainer = new UnityContainer();

        // register all your components with the container here
        // it is NOT necessary to register your controllers

        // e.g. container.RegisterType<ITestService, TestService>();
        myContainer.RegisterType<IMasterDataClient, MasterDataClient>("MDS");
        myContainer.RegisterType<ILinksManager, LinksManager>("LDS");
        GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(container);
    }
}

Web控制器:

代码语言:javascript
复制
using (var container = new UnityContainer())
{
       container.Resolve<IMasterDataClient>("MDS");
       container.Resolve<ILinksManager>("LDS");
}

MasterDataClient接口实现类:

代码语言:javascript
复制
public class MasterDataClient : HalClient, IMasterDataClient, IHalClient, ICrestaClient
{
    public MasterDataClient(IApiClient apiClient, IUriDispenser dispenser);
}
EN

回答 1

Stack Overflow用户

发布于 2016-09-05 08:09:54

你这里有三个问题。

问题1.您正在创建一个新容器:

代码语言:javascript
复制
using (var container = new UnityContainer())
{
       container.Resolve<IMasterDataClient>("MDS");
       container.Resolve<ILinksManager>("LDS");
}

container将为空,并有0注册。这不是你注册的同一个容器。有几种方法可以解决这个问题:

问题1-解决方案1:不要注入容器。注入依赖项.,而不是使用容器,您应该直接将依赖项注入到控制器:

代码语言:javascript
复制
public class MyApiController : ApiController
{
    IMasterDataClient _masterDataClient;
    ILinksManager _linksManager


    public MyApiController(IMasterDataClient masterDataClient, ILinksManager linksManager)
    {
        _masterDataClient = masterDataClient;
        _linksManagerlinksManager;
    }
}

这样可以避免服务定位器模式和对容器本身的依赖。如果使用的是命名注册,则可能需要使用Dependency-attribute。

如何将命名依赖项注入构造函数?

问题1-解决方案2:注入您的容器而不是创建一个新的容器。如果您确实出于某种原因需要您的控制器,那么您应该尝试注入它。这样,您将得到相同的容器,您使用您的注册。

代码语言:javascript
复制
public class MyApiController : ApiController
{
    IUnityContainer _container;


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

问题1-解决方案3:保持对容器的静态引用。作为最后手段,您可以将容器保持为静态实例。

代码语言:javascript
复制
public static class IocContainer
{
    private static readonly Lazy<IUnityContainer> Container = new Lazy<IUnityContainer>(() =>
    {
        var container = new UnityContainer();
        return container;
    });

    public static IUnityContainer Instance
    {
        get { return Container.Value; }
    }
}

在你的注册中:

代码语言:javascript
复制
public static class UnityConfig
{
    public static void RegisterComponents()
    {
        var container = IocContainer.Instance;

        // register all your components with the container here
        // it is NOT necessary to register your controllers

        // e.g. container.RegisterType<ITestService, TestService>();
        myContainer.RegisterType<IMasterDataClient, MasterDataClient>("MDS");
        myContainer.RegisterType<ILinksManager, LinksManager>("LDS");
        GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(container);
    }
}

用法:

代码语言:javascript
复制
IocContainer.Instance.Resolve<IMasterDataClient>("MDS");

问题2.您似乎没有注册MasterDataClient**.**的依赖项。

它对IApiClientIUriDispenser有依赖关系。他们也需要注册。

问题3.将依赖项解析器分配给错误的容器

您目前创建了两个容器-- myContainercontainer。您将注册到一个容器,然后使用另一个容器作为DependencyResolver。您可以通过删除myContainer来解决这个问题,并且只使用container。否则,您将无法使用您的注册在Web。

代码语言:javascript
复制
public static class UnityConfig
{
    public static void RegisterComponents()
    {
        var container = new UnityContainer();

        // register all your components with the container here
        // it is NOT necessary to register your controllers

        // e.g. container.RegisterType<ITestService, TestService>();
        container.RegisterType<IMasterDataClient, MasterDataClient>("MDS");
        container.RegisterType<ILinksManager, LinksManager>("LDS");
        GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(container);
    }
}

更新:

我不知道为IApiClient和IUriDispenser实现类,因为它是第三方dll,所以如何注册它?

统一需要知道在解析接口时要使用哪个实现。因此,不知何故,您需要告诉联合使用什么实现。马克·西曼在下面的问题中给出了一个很好的答案:

用于动态解析程序集的统一IoC

它扫描程序集以查找接口的实现,然后注册它们/ It。

另外,您也可以使用公约登记,它使您能够同时进行多个注册:

代码语言:javascript
复制
container.RegisterTypes(
    AllClasses.FromLoadedAssemblies(),
    WithMapping.MatchingInterface,
    WithName.Default,
    WithLifetime.ContainerControlled);

请注意,这将注册所有实现,包括您自己的实现。如果您只希望第三方实现,您应该能够这样做:

代码语言:javascript
复制
// Get the assemblies where IApiClient exists.
IEnumerable<Assembly> assemblies = AppDomain.CurrentDomain.GetAssemblies()
    .Where(x => x.GetTypes().Contains(typeof (IApiClient)));

// Register all implementations based on convention.
container.RegisterTypes(AllClasses.FromAssemblies(assemblies), 
    WithMappings.FromMatchingInterface,
    WithName.Default,
    WithLifetime.ContainerControlled); // Maybe another lifetime manager?

更新2:

确保控制器具有无参数的公共构造函数。

上面的错误可能有很多原因,其中大部分都包含在以下问题中:

无法将DBContext注入我的Web 2控制器

确保控制器有无参数的公共构造函数错误。

错误:确保控制器具有无参数的公共构造函数webapi

大多数情况下,是统一告诉你,你试图解决一些你没有注册的事情。或者你根本没有注册DependencyResolver。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39323761

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档