我想在我的应用程序中以相同的方式处理不同类型的文档 因此: 我有这样的通用界面。
public interface IDocHandler<T>where T: class
{
T Document { get;set;}
void Load(T doc);
void Load(string PathToDoc);
void Execute();
void Execute(T doc);
}
对于不同类型的文档,我实现了这个接口。
例如:
public class FinanceDocumentProcessor:IDocumentHandler<ReportDocument>
{}
public class MarketingDocumentProcessor:IDocumentHandler<MediaDocument>
{}
然后我当然可以这样做:
IDocumentHandler<ReportDocument> docProc= new FinanceDocumentProcessor();
如果我知道如何在运行时注入T以使上面的线路松散耦合,那将是非常令人兴奋的......
IDocumentHandler<ReportDocument> docProc = container.resolve("FinanceDocumentProcessor());
但我想根据配置来决定我想要我的FinanceDomcumentProcessor还是我的MarketingDocumentProcessor ...因此我也必须在左侧网站上注入T ... 由于我必须使用c#2.0,我不能使用魔术这个词“var”,这在这种情况下会有很多帮助...但是我怎样才能将它设计为开放灵活...
对于所有评论的误解和感谢表示歉意,但我还有另一个例子来表示我的挑战(也许我使用了错误的设计)...... 但我试一试:相同的情况,但不同的解释
示例图片我有:
ReportingService,Crystal,ListAndLabel
三种不同的报告文档类型。我有一个通用的Handler IReportHandler<T>
(与上面相同),这个Handler提供了处理报告Document的所有功能。
例如
ChrystalReportHandler:IReportHandler<CrystalReportDocument>
现在我想使用类似Unity(或其他框架)的框架来进行依赖注入,以决定是否要使用Crystal,Reportingservices
或List和Label。
当我指定我的映射时,我可以注入ChrystalReportHandler
但是如何在左侧或更好的单词ReportDocument
中注入T。
IReportHandler<T (this needs also to be injected)> = IOContainer.Resolve(MyMappedType here)
我的问题是左站点,当然因为它与类型耦合但我有我的映射...是否可以基于Mapping生成对象并分配映射类型?或者基本上也在左侧注入T? 或者这种方法不适合这种情况。
答案 0 :(得分:2)
我认为,根据您当前的设计,您在IDocumentHandler
与特定文档(ReportDocument
或MediaDocument
)之间创建了“依赖关系”,因此如果您想使用{{ 1}}直接在你的代码中你必须假设你的容器会给你这个。在这种情况下,容器不应负责解析文档类型。
你会考虑改变你的设计吗?
IDocumentHandler<ReportDocument or MediaDocument>
答案 1 :(得分:1)
您需要在左侧使用非通用接口。
尝试:
public interface IDocumentHandler { }
public interface IDocumentHandler<T> : IDocumentHandler { }
这将创建两个接口。将所有常见的,非特定于T的特性放入基础界面,以及通用的其他所有内容。
由于你想要解析一个对象的代码,你不知道处理器的类型,你无法在那里调用任何特定于T的代码,所以你不会丢失任何东西使用非通用接口。
修改:我注意到我的答案已被低估了。如果人们贬低事情会留下评论,为什么他们这样做会很好。我不关心声望点,这点只是微小的噪音,但如果答案有严重错误,那么我想知道我可以删除答案(如果它偏离目标)或纠正它。
现在在这种情况下,我怀疑原来的被问者是否已经对它进行了贬低,因此要么没有发布足够的信息,所以他实际上询问的不是他所询问的内容,或者他不太了解我的内容。回答,这是可以理解的,因为它有点短,或者是那个不理解它的人,也是出于同样的原因。
现在,详细说明。
你不能在左侧注射任何东西。那是不可能的。该代码必须编译,正确,并在编译时100%“存在”。对于那部分,你不能说“我们会告诉你T在运行时是什么”。这是不可能的。
所以你唯一留下的就是彻底删除T.使用依赖项的代码完全不依赖于T.或者,至少使用反射来发现T是什么,并根据这些知识做事。
这就是你所能做的一切。根据您从右侧方法返回的内容,您无法使左侧的代码自行更改。
这是不可能的。
因此我的回答。
答案 2 :(得分:1)
如果我理解正确,您有两种选择。
如果您有实现它的接口IDocHandler和多个类,则必须明确注册每个类型,如下所示:
container.AddComponent&GT;(typeof运算(FooHandler));
如果您有一个类DocHandler,则可以使用开放泛型类型
注册组件container.AddComponent(typeof(IDocHandler&lt;&gt;),typeof(DocHandler&lt;&gt;));
然后每次解析IDocHandler时,您将获得DocHandler的实例,当您解析IDocHandler时,您将获得DocHandler
希望有所帮助