从通用方法返回对象作为接口

Zav*_*ael 2 c# architecture design-patterns interface factory-method

我有一个接口InterfaceBase和一些从它派生的接口Interface1, Interface2.接下来我有实现InterfaceX接口的类,而不是基类.

现在,我是仿制药的初学者,这样的许多新方法在我的头脑中变得非常混乱:(.我想创建工厂(静态类),我称之为类似的东西

Interface1 concrete1 = Factory.Get<Interface1>();
Run Code Online (Sandbox Code Playgroud)

这是我的(示例)工厂实现,不起作用:

  public static class Factory {

    public static T Get<T>() where T: InterfaceBase{

      Type type = typeof(T);

      //return new Concrete1() as T; // type T cannot be used with the as
      //return new Concrete1() as type; //type not found
      //return new Concrete1(); // cannot implicitly convert
      //return new Concrete1() as InterfaceBase; //cannot convert IBase to T
      //return new Concrete1() as Interface1; //cannot convert Interface1 to T
    }
  }
Run Code Online (Sandbox Code Playgroud)

我想要实现的是从应用程序的其余部分隐藏类(它们是webservice处理程序)以轻轻地交换它们.我想使用工厂,因为类将是单例,它们将存储在工厂内的Dictionary中,因此工厂可以通过此方法将它们传播到应用程序,但作为接口..也许我没有正确使用约束我是做错了什么?我的方法不好吗?可以有更好的东西,也许整个建筑都要重新设计?图表更好地展示了架构.工厂不在其中

rse*_*nna 5

你正在寻找的是"穷人依赖注射".我想你应该使用一个真正的IoC容器,有很多选项(Unity,Castle Windsor,Ninject ......).

但无论如何,如果你坚持自己做,那就去@Sergey Kudriavtsev推荐.只需确保为每个接口返回适当的具体类.像这样的东西:

public interface InterfaceBase { }
public interface Interface1 : InterfaceBase { }
public interface InterfaceX : InterfaceBase { }

public class Concrete1 : Interface1 { }
public class ConcreteX : InterfaceX { }

public static class Factory
{
    public static T Get<T>()
        where T : InterfaceBase
    {
        if (typeof(Interface1).IsAssignableFrom(typeof(T)))
        {
            return (T)(InterfaceBase)new Concrete1();
        }
        // ...
        else if (typeof(InterfaceX).IsAssignableFrom(typeof(T)))
        {
            return (T)(InterfaceBase)new ConcreteX();
        }

        throw new ArgumentException("Invalid type " + typeof(T).Name, "T"); // Avoids "not all code paths return a value".
    }
}
Run Code Online (Sandbox Code Playgroud)

你通过将接口引用传递给工厂来调用它:

var instance = factory.Get<Interface1>();
Run Code Online (Sandbox Code Playgroud)