使用Structure Map替换泛型类型参数中的抽象类型

时间:2012-04-03 23:07:03

标签: c# generics abstract-class structuremap

我有以下带有泛型类型参数的类。

public class ContentService<T> : IContentService where T : DataString, new()
{       
    public ContentService(IEnvironment environment, 
                          ILogger logger)
    {
        _environment = environment;
        _logger = logger;
    }
...
}

DataString是一个抽象类,每当我的应用程序创建ContentService实例时,我都希望Structure Map使用具体的实现(XmlDataString)。当我这样做时,Structure Map已经注入了IEnvironment和ILogger的具体实现:

版本1:

_contentService = ObjectFactory.GetInstance<ContentService<DataString>>();

...但是当我单步执行时,ContentService是使用DataString的类型参数创建的,而不是XmlDataString。我在web.config中有这三个设置默认实例的条目:

  • IEnvironment - &gt; TestEnvironment
  • ILogger - &gt; Log4NetLogger
  • DataString - &gt; XmlDataString

结构地图网站有this来说明泛型,但我似乎无法将这个例子与我的实际问题联系起来。

这种方法有效,但我丢失了构造函数参数的自动连接,看起来很丑陋: 第2版​​:

Type typeOfDataString = ObjectFactory.GetInstance<DataString>().GetType();
Type genericClass = typeof(ContentService<>);
Type constructedClass = genericClass.MakeGenericType(typeOfDataString);
_contentService = (IContentService)Activator.CreateInstance(constructedClass, 
            ObjectFactory.GetInstance<IEnvironment>(), 
            ObjectFactory.GetInstance<ILogger>());

有人能告诉我第一版中我做错了什么,或者我如何改进第二版?

1 个答案:

答案 0 :(得分:1)

首先,当您编写ObjectFactory.GetInstance<ContentService<DataString>>()时,您无法返回ContentService<XmlDataString>,因为这是一种不同的,不兼容的类型。

但似乎你真的想要IContentService,所以写下:ObjectFactory.GetInstance<IContentService>()。这将返回您注册的IContentService的实现,因此您应该这样做:为ContentService<XmlDataString>注册IContentService。您XmlDataString注册DataString的事实与此无关。

如果在web.config中表示泛型类型ContentService<XmlDataString>时遇到问题,我认为使用泛型类型的.Net表示(而不是C#的表示)应该有效。在你的情况下,这可能是ContentService`1[[XmlDataString]],可能还有添加的命名空间和可能的程序集。