.net 向多个层传递信息的统一注入问题

.net 向多个层传递信息的统一注入问题,.net,dependency-injection,unity-container,enterprise-library,.net,Dependency Injection,Unity Container,Enterprise Library,我试图使用Unity对一些横切类进行依赖注入。现在,我有一些缓存基础设施,这些基础设施是围绕MS enterprise library构建的。我正在包装它,因为我以后可能想用别的东西。此外,我可能希望混合和匹配不同的缓存存储 因此,我有一个通用的缓存接口和一个具体的实现,如下所示 public interface ICacheProvider { void Add(object key, object value); void Remove(object key);

我试图使用Unity对一些横切类进行依赖注入。现在,我有一些缓存基础设施,这些基础设施是围绕MS enterprise library构建的。我正在包装它,因为我以后可能想用别的东西。此外,我可能希望混合和匹配不同的缓存存储

因此,我有一个通用的缓存接口和一个具体的实现,如下所示

public interface ICacheProvider
{
    void Add(object key, object value);

    void Remove(object key);

    object GetData(object key);

    void Flush();
}

public class MyCacheProvider : ICacheProvider
{
    private ICacheManager cacheManager;

    public MyProvider(ICacheManager manager)
    {
        cacheManager = manager;
    }
}
ICacheManager是企业库中的类型。我试图做的是使用unity在运行时解析缓存管理器。此外,对于不同的缓存存储,这可能是不同的。现在,它们都解析为我显示的类型。这是我的统一配置

<unity>
<typeAliases>
  <typeAlias alias="string" type="System.String, mscorlib" />
  <typeAlias alias="ICacheProvider" type="DomainBase.Caching.ICacheProvider, DomainBase" />
  <typeAlias alias="MSCacheProvider" type="Caching.MyCacheProvider, Caching" />
</typeAliases>
<containers>
  <container>
    <types>
      <register type="ICacheProvider" mapTo="MSCacheProvider" />
    </types>
  </container>
</containers>
这允许企业库自动从配置中提取信息,并根据其中的内容进行解析。问题是,当我深入到两个级别时(即,我没有直接解析到企业库接口),解析失败,因为我没有命名的解析。给定企业库扩展,不需要命名解析,因为提供的扩展注册了正确的解析,就像它被命名一样。尽管如此,我认为Unity无法自行实现将我的界面映射到企业库的神奇飞跃。下面是一些示例代码

//note that's ICacheProvider which my interface for abstracting caching.  NOT
//the enterprise library interface
ICacheProvider customersCache = rootContainer.Resolve<ICacheProvider>(); //works
ICacheProvider productsCache = rootContainer.Resolve<ICacheProvider>("ProductsCache"); //doesn't work
//注意,这是我用于抽象缓存的接口的ICacheProvider。不
//企业库接口
ICacheProvider customersCache=rootContainer.Resolve()//作品
ICacheProvider productsCache=rootContainer.Resolve(“productsCache”)//不起作用
第一个示例有效,因为有默认分辨率,但是第二个示例失败,因为我没有“产品”的命名分辨率。有什么好办法来处理这种情况吗?我不想为添加到系统中的每个不同缓存存储都指定解析,因为它们已经在缓存配置中定义。我会尝试不同类型的注入,但在这个场景中,您几乎必须使用构造函数注入

此外,我还尝试显式定义命名注册,即使定义了两个独立的实例,我仍然会得到相同的CacheManager实例。我想,一旦完成了初始解析,它会查看构造函数,没有“名称”,只是基于默认值进行注入


感谢您的帮助

找到了我自己问题的答案。我能找到它的唯一方法是使用自定义扩展并检查类型。这是一个样品

 public class WrappedResolver : UnityContainerExtension
{

    protected override void Initialize()
    {
        this.Context.Strategies.Add(new WrappedBuilder(this.Container), Microsoft.Practices.Unity.ObjectBuilder.UnityBuildStage.PreCreation);

    }
}

public class WrappedBuilder : BuilderStrategy
{
    IUnityContainer baseContainer;

    public WrappedBuilder(IUnityContainer container)
    {
        baseContainer = container;
    }

    public override void PreBuildUp(IBuilderContext context)
    {

        if (context.BuildKey.Type.Name.Contains("ICacheProvider") && context.OriginalBuildKey.Name != null)
        {
            string originalName = context.OriginalBuildKey.Name;
            Type mytype = Type.GetType("Microsoft.Practices.EnterpriseLibrary.Caching.ICacheManager, Microsoft.Practices.EnterpriseLibrary.Caching");
            Type originalType = context.BuildKey.Type;// Type.GetType("DomainBase.Caching.ICacheProvider, DomainBase");
            context.Existing = baseContainer.Resolve(originalType, new ParameterOverride("manager",
                                                                         new ResolvedParameter(mytype, originalName)));

            context.BuildComplete = true;

        }
        base.PreBuildUp(context);
    }   
}

找到了我自己问题的答案。我能找到它的唯一方法是使用自定义扩展并检查类型。这是一个样品

 public class WrappedResolver : UnityContainerExtension
{

    protected override void Initialize()
    {
        this.Context.Strategies.Add(new WrappedBuilder(this.Container), Microsoft.Practices.Unity.ObjectBuilder.UnityBuildStage.PreCreation);

    }
}

public class WrappedBuilder : BuilderStrategy
{
    IUnityContainer baseContainer;

    public WrappedBuilder(IUnityContainer container)
    {
        baseContainer = container;
    }

    public override void PreBuildUp(IBuilderContext context)
    {

        if (context.BuildKey.Type.Name.Contains("ICacheProvider") && context.OriginalBuildKey.Name != null)
        {
            string originalName = context.OriginalBuildKey.Name;
            Type mytype = Type.GetType("Microsoft.Practices.EnterpriseLibrary.Caching.ICacheManager, Microsoft.Practices.EnterpriseLibrary.Caching");
            Type originalType = context.BuildKey.Type;// Type.GetType("DomainBase.Caching.ICacheProvider, DomainBase");
            context.Existing = baseContainer.Resolve(originalType, new ParameterOverride("manager",
                                                                         new ResolvedParameter(mytype, originalName)));

            context.BuildComplete = true;

        }
        base.PreBuildUp(context);
    }   
}