首页 > 解决方案 > 使用通用接口实现工厂

问题描述

我正在从合同中抽象出依赖关系以解耦依赖关系

// Abstraction -- This can be published as contract where implementation needs to implement method. Most importantly 3rd party types are not present/tied to contract

public interface ISourceFactory {
   T GetSource<T>();
}


// Implementation which depends on specific source like 3rd party

public class SourceFactory {
    public T GetSource<T>()   //Unable to make this work
    {
        Type listType = typeof(T);
        if (listType == typeof(SomeBase))
        {
            return _connection.GetSource<T>();
        }
        if(listType == typeof(ExternalBase)){
            return _exconnection.GetSource<T>();
        }
        throw new Exception("Not supported");
    }

    private Connection _connection;
    private ExternalConnection _exconnection;
}

// 3rd party implementation
public class Connection {
    public T GetSource<T> where T : SomeBase
}

// 3rd party implementation
public class ExternalConnection {
    public T GetSource<T> where T : ExternalBase
}

但是,我无法使 SourceFactory.GetSource 正常工作,因为它认为 T 不能用作通用参数。

谁能建议这个问题的通用方法是什么?

标签: c#genericsdesign-patternsinterface

解决方案


As said in the comments it's not possible per se, because connections must have something in common to be abstracted as generic. You are using 3. party components, but as you are trying to use them in one factory, I suppose you want to get same data from them. So I suggest to define an interface where you define the common part that you need:

public interface IConnection{
string GetConnectionString();
...
}

Than you wrap your 3d party connections:

public class SomebaseWrapper : IConnection{
public SomebaseWrapper(SomeBase b){
}
...
}

Than you ask for the wrapper in your factory:

public interface ISourceFactory {
   T GetSource<T>() where T is IConnection;
}

And finally you ask for SomebaseWrapper and implement it like this:

public T GetSource<T>() where T : IConnection
        {
            Type listType = typeof(T);
            if (listType == typeof(SomebaseWrapper))
            {
                return new SomebaseWrapper(_connection.GetSource<SomeBase>());
            }
            if (listType == typeof(ExternalBaseWrapper))
            {
                return new (ExternalBaseWrapper)(_exconnection.GetSource<T>());
            }
            throw new Exception("Not supported");
        }

推荐阅读