我有以下带有通用类型参数的类。

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


DataString是一个抽象类,我希望结构图在我的应用程序创建ContentService实例时使用具体的实现(XmlDataString)。执行此操作时,结构图已经在注入IEnvironment和ILogger的具体实现:

版本1:

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


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


IEnvironment->测试环境
ILogger-> Log4NetLogger
数据字符串-> 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>());


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

最佳答案

首先,当您写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]],可能还添加了名称空间和程序集。

09-30 00:15