DependencyResolver不解析依赖关系。为什么呢?

时间:2016-01-05 12:33:21

标签: c# dependency-injection inversion-of-control unity-container

我在项目中使用Unity作为我的IoC。

UnityConfig设置如下......

public static class UnityConfig
{
    private static readonly IUnityContainer container = new UnityContainer();

    public static void ConfigureIoCContainer()
    {
        My.Composition.Builder.Compose(container);

        DependencyResolver.SetResolver(new UnityDependencyResolver(container));
    }

    /// <summary>
    /// Gets the configured Unity container.
    /// </summary>
    public static IUnityContainer GetConfiguredContainer()
    {
        return container;
    }
}

My.Composition.Builder.Compose()这样做......

    public static void Compose(IUnityContainer container)
    {
        var types = new List<Type>();

        types.AddRange(Services.Interface.Builder.GetTypes(container));
        types.AddRange(Services.Builder.GetTypes(container));            
        // ... lots more assemblies referenced here

        var distinctTypes = types.Distinct();

        container.RegisterTypes(distinctTypes, WithMappings.FromMatchingInterface, WithName.Default, WithLifetime.PerResolve);
    }

现在,在上面引用的2个程序集中,我返回3种类型;来自第一个的IConfigUowISecurityUowIResourceUow以及来自第二个的ConfigUowSecurityUowResourceUow

如果我在调用UnityConfig中My.Composition.Builder.Compose(container)之后的行中放置一个断点并查看已注册类型的列表,我可以看到所有我应该...

{Microsoft.Practices.Unity.ContainerRegistration}
    LifetimeManager: {Microsoft.Practices.Unity.PerResolveLifetimeManager}
    LifetimeManagerType: {Name = "PerResolveLifetimeManager" FullName = "Microsoft.Practices.Unity.PerResolveLifetimeManager"}
    MappedToType: {Name = "ConfigUow" FullName = "My.Services.Security.ConfigUow"}
    Name: null
    RegisteredType: {Name = "IConfigUow" FullName = "My.Services.Interface.Security.IConfigUow"}

{Microsoft.Practices.Unity.ContainerRegistration}
    LifetimeManager: {Microsoft.Practices.Unity.PerResolveLifetimeManager}
    LifetimeManagerType: {Name = "PerResolveLifetimeManager" FullName = "Microsoft.Practices.Unity.PerResolveLifetimeManager"}
    MappedToType: {Name = "SecurityUow" FullName = "My.Services.Security.SecurityUow"}
    Name: null
    RegisteredType: {Name = "ISecurityUow" FullName = "My.Services.Interface.Security.ISecurityUow"}

{Microsoft.Practices.Unity.ContainerRegistration}
    LifetimeManager: {Microsoft.Practices.Unity.PerResolveLifetimeManager}
    LifetimeManagerType: {Name = "PerResolveLifetimeManager" FullName = "Microsoft.Practices.Unity.PerResolveLifetimeManager"}
    MappedToType: {Name = "ResourceUow" FullName = "My.Services.Localization.ResourceUow"}
    Name: null
    RegisteredType: {Name = "IResourceUow" FullName = "My.Services.Interface.Localization.IResourceUow"}

但是,如果我让下一行执行设置DependencyResolver并调用

DependencyResolver.Current.GetService<IConfigUow>();

返回null的值。致电

DependencyResolver.Current.GetService<ISecurityUow>();

工作并返回SecurityUow的实例。尝试解决IResourceUow也失败了。

对于我的生活,我无法看到我做错了什么。有人有什么想法吗?

更新

好的,所以通过调用container.Resolve(IConfigUow)我得到了一个被DependencyResolver屏蔽的异常。

该错误表明我错过了类型映射。 ConfigUow的构造函数看起来像这样......

    public ConfigUow(ICrudRepo<AM.Configuration> crudRepo = null) : base(crudRepo)
    {
        CrudRepo = crudRepo ?? DependencyResolver.Current.GetService<IConfigRepo>();
        Ctx = CrudRepo.GetContext();
    }

我不知道我需要为使用泛型的类型显式调用RegisterType()

所以,我需要做的就是注册这样的合适类型......

container.RegisterType(typeof (ICrudRepo<>), typeof (CrudRepo<>)); 

这一切都奏效了。

对于未来的读者,这些页面证明是有帮助的......

1 个答案:

答案 0 :(得分:0)

答案是DependencyResolver掩盖了IoC容器抛出异常的事实。

发现解决问题并不困难。请读者查看原始问题的更新,了解我必须修复的内容以及我是如何修复的。