在调试代码时,我会得到此异常:
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:
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控制器:
using (var container = new UnityContainer())
{
container.Resolve<IMasterDataClient>("MDS");
container.Resolve<ILinksManager>("LDS");
}MasterDataClient接口实现类:
public class MasterDataClient : HalClient, IMasterDataClient, IHalClient, ICrestaClient
{
public MasterDataClient(IApiClient apiClient, IUriDispenser dispenser);
}发布于 2016-09-05 08:09:54
你这里有三个问题。
问题1.您正在创建一个新容器:
using (var container = new UnityContainer())
{
container.Resolve<IMasterDataClient>("MDS");
container.Resolve<ILinksManager>("LDS");
}此container将为空,并有0注册。这不是你注册的同一个容器。有几种方法可以解决这个问题:
问题1-解决方案1:不要注入容器。注入依赖项.,而不是使用容器,您应该直接将依赖项注入到控制器:
public class MyApiController : ApiController
{
IMasterDataClient _masterDataClient;
ILinksManager _linksManager
public MyApiController(IMasterDataClient masterDataClient, ILinksManager linksManager)
{
_masterDataClient = masterDataClient;
_linksManagerlinksManager;
}
}这样可以避免服务定位器模式和对容器本身的依赖。如果使用的是命名注册,则可能需要使用Dependency-attribute。
问题1-解决方案2:注入您的容器而不是创建一个新的容器。如果您确实出于某种原因需要您的控制器,那么您应该尝试注入它。这样,您将得到相同的容器,您使用您的注册。
public class MyApiController : ApiController
{
IUnityContainer _container;
public MyApiController(IUnityContainer container)
{
_container = container;
}
}问题1-解决方案3:保持对容器的静态引用。作为最后手段,您可以将容器保持为静态实例。
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; }
}
}在你的注册中:
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);
}
}用法:
IocContainer.Instance.Resolve<IMasterDataClient>("MDS");问题2.您似乎没有注册MasterDataClient**.**的依赖项。
它对IApiClient和IUriDispenser有依赖关系。他们也需要注册。
问题3.将依赖项解析器分配给错误的容器
您目前创建了两个容器-- myContainer和container。您将注册到一个容器,然后使用另一个容器作为DependencyResolver。您可以通过删除myContainer来解决这个问题,并且只使用container。否则,您将无法使用您的注册在Web。
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,所以如何注册它?
统一需要知道在解析接口时要使用哪个实现。因此,不知何故,您需要告诉联合使用什么实现。马克·西曼在下面的问题中给出了一个很好的答案:
它扫描程序集以查找接口的实现,然后注册它们/ It。
另外,您也可以使用公约登记,它使您能够同时进行多个注册:
container.RegisterTypes(
AllClasses.FromLoadedAssemblies(),
WithMapping.MatchingInterface,
WithName.Default,
WithLifetime.ContainerControlled);请注意,这将注册所有实现,包括您自己的实现。如果您只希望第三方实现,您应该能够这样做:
// 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:
确保控制器具有无参数的公共构造函数。
上面的错误可能有很多原因,其中大部分都包含在以下问题中:
大多数情况下,是统一告诉你,你试图解决一些你没有注册的事情。或者你根本没有注册DependencyResolver。
https://stackoverflow.com/questions/39323761
复制相似问题