通用接口的工厂模式

Factory pattern from generic interface

我有通用接口 IProcessor<T, TU> 和它的 2 个实现:

StandartDocumentProcessorModDocuemntProcessor.

我将使用工厂模式(或类似的东西)来实例化变量 currentProcessor

IProcessor<T, TU> currentProcessor = Factory.Create(argument).

然后我要调用方法currentProcessor.ProcessFrom()currentProcessor.ProcessTo()

第一个问题:不可能为 currentProcessor 使用 IProcessor<T,TU>IProcessor 类型,因为 CLR 不允许这样做并坚持使用特定类型对于我的变量。

第二个问题:我在网上冲浪,发现使用 ReflectionActivator.CreateInstance() 的丑陋解决方案与降低性能。

请指教,是否可以避免:反射、转换为 object 或使用 dynamic

UPD: IProcessor.cs

public interface IProcessor<T, TU> where T : DocumentValidation
    {
        HtmlContent RetrieveDocument(SearchItem item);

        bool ValidateObject(T obj);

        T ProcessFrom(HtmlContent content);

        TU ProcessTo(T source);

        bool SaveTo(TU target, T source);

    } 

首次实施 IProcessor - StandardDocumentProcessor.cs

class StandardDocumentProcessor : IProcessor<Document, XmlDocument>
    {
        public HtmlContent RetrieveDocument(SearchItem item)
        {
            throw new NotImplementedException();
        }

        public bool ValidateObject(Document obj)
        {
            throw new NotImplementedException();
        }

        public Document ProcessFrom(HtmlContent content)
        {
            throw new NotImplementedException();
        }

        public XmlDocument ProcessTo(Document source)
        {
            throw new NotImplementedException();
        }

        public bool SaveTo(XmlDocument target, Document source)
        {
            throw new NotImplementedException();
        }
    }

IProcessor 的第二次实施 - ModDocumentProcessor.cs

public class ModDocumentProcessor : IProcessor<ModDocument, XmlDocument>
    {
        public HtmlContent RetrieveDocument(SearchItem item)
        {
            throw new NotImplementedException();
        }

        public bool ValidateObject(ModDocument obj)
        {
            throw new NotImplementedException();
        }

        public ModDocument ProcessFrom(HtmlContent content)
        {
            throw new NotImplementedException();
        }

        public XmlDocument ProcessTo(ModDocument source)
        {
            throw new NotImplementedException();
        }

        public bool SaveTo(XmlDocument target, ModDocument source)
        {
            throw new NotImplementedException();
        }
    }

现在我要创建工厂模式来实例化 IProcessor<T, TU> 一些特定的 class。

????? currentProcessor = Factory.Create(input_argument_which_allows_to_define_concrete_implementation_of_IProcessor)

无所谓,在这里展示Create方法的实现。我想问一下 返回 Create 方法的类型

因为 C# 4.0 你可以简单地将你的工厂方法声明为动态的并且它会起作用:

public static dynamic Create(string at) {
   if (condition)
     return new StandardDocumentProcessor();
   else
     return new ModDocumentProcessor();
}

调用:

dynamic m = Create("mod");

当然,这就像作弊,因为使用 dynamic 你会失去类型安全性(有运行时异常的风险)并且会降低性能。

如果不知道您的应用域,但如果这方面对您来说很重要,我会更改一些内容并尝试通用 out 参数。

public interface IProcessor<out T, out TU> where T : DocumentValidation {
    HtmlContent RetrieveDocument(SearchItem item);
    bool ValidateObject(DocumentValidation obj);
    T ProcessFrom(HtmlContent content);
    TU ProcessTo(DocumentValidation source);
}

工厂:

public static IProcessor<DocumentValidation, ProcessResult> Create(string at) {
  if (condition(at))
    return new StandardDocumentProcessor();
  else
    return new ModDocumentProcessor();
  }

请注意,我删除了 SaveTo 方法,因为它不适合此模式。如果您仍然需要它,请将其移至另一个界面。 ProcessResult 是 class 的基础/XmlDocument 的接口。

另请注意:如果您根本不使用泛型并使用继承/基础 classes,一切都会更简单。 工厂模式通常用于隐藏和封装实现细节和类型,包括一些通用参数。如果你想从你的代码中获取类型信息工厂,也许使用工厂不是最好的主意。