使用泛型的Unity配置映射

时间:2016-04-11 16:28:31

标签: c# .net unity-container

我有使用泛型的类和接口。我们使用配置文件来管理与Microsoft Unity for DI的映射。

类别:

namespace Acme.Core
{    
  public class CommonCache<T> : ICommonCache<T>
  {
    private string _cacheKey;

    public CommonCache(string cacheKey)
    {
        _cacheKey = cacheKey;
    }

    public IReadOnlyList<T> GetAll(List<T> dataList)
    {
       // Code returns IReadOnlyList<T>
    }
}   

接口:

namespace Acme.Core.Interfaces
{
    public interface ICommonCache<T>
    {
        IReadOnlyList<T> GetAll(List<T> dataList);
    }
}

我所希望的是这样的:

 <unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
    <assembly name="Acme.Core" />
    <namespace name="Acme.Core" />
    <namespace name="Acme.Core.Interfaces" />

   <container name="Default">
    <register type="ICommonCache[*]" mapTo="CommonCache[*]">
      <constructor>
       <param name="cacheKey" value="*" />
      </constructor>
    </register>
   </container>
  </unity>

我知道*语法不正确但我的目标是允许为类型传递任何类型,并为通用类型传递mapTo。对于构造函数,我想传递cacheKey参数的值,我有值=&#34; *&#34;说明传递任何价值的目标。

此映射的正确语法是什么?

2 个答案:

答案 0 :(得分:1)

通过首先注册开放式泛型类型,然后(如果您愿意)覆盖使用封闭式泛型的注册,您可以完成类似于您的操作。

首先添加一个默认构造函数,以便在没有关闭的通用注册时实现您希望的行为......

public CommonCache()
{
    _cacheKey = typeof(T).FullName;
}

Open Generics Registration

<register type="ICommonCache`1" mapTo="CommonCache`1">
  <!-- Use the default constructor -->
  <constructor />
</register>

关闭泛型注册

<register type="ICommonCache`1[BusinessType]" mapTo="CommonCache`1[BusinessType]">
  <constructor>
    <param name="cacheKey" value="BusinessTypeCacheKeyOverride" />
  </constructor>
</register>

但我建议你改为从构造函数中删除值类型。这可以通过引入一个新类作为依赖项来设置缓存键映射的类型来完成。这可以从配置中读取。

public interface ICacheKeyMap
{
    string GetCacheKey(Type t);
    void SetCacheKey(Type t, string cacheKey);
}

答案 1 :(得分:0)

根据documentation关于

Specifying Types in the Configuration File.

通用类型

泛型类型的CLR类型名称语法非常详细,它也不允许使用别名之类的东西。 Unity配置系统允许通用类型的简写语法,也允许别名和类型搜索。

要指定一个封闭的泛型类型,请在方括号中以逗号分隔的列表中提供类型名称,后跟类型参数。

Unity简写类似于以下示例。 XML

<container>
    <register type="IDictionary[string,int]" </register>
</container>

如果您希望使用程序集名称限定类型作为类型参数,而不是别名或自动找到的类型,则必须将整个名称放在方括号中,如以下示例所示: XML

<register type="IDictionary[string, [MyApp.Interfaces.ILogger, MyApp]]"/>

要指定打开的泛型类型,只需省略类型参数即可。您有两种选择:

  • 使用`N的CLR表示法,其中N是通用参数的数量。

  • 使用带逗号的方括号表示通用参数的数量。

    通用类型|使用CLR表示法配置文件XML |使用逗号表示法配置文件XML

    IList =&gt; IList`1 =&gt;的IList []

    IDictionary =&gt; IDictionary`2 =&gt; IDictionary的[,]