泛型工厂方法,用于从基类实例化派生类

本文关键字:基类 实例化 派生 用于 工厂 方法 泛型 | 更新日期: 2023-09-27 18:35:03

我正在创建一个工厂方法,该方法使用通用抽象类型参数使用反射返回具体派生类型的实例。例如。

public abstract class ServiceClientBase : IServiceClient
{
}
public abstract class Channel : ServiceClientBase
{
}
public class ChannelImpl : Channel
{
}
public class ServiceClientFactory
{
    public T GetService<T>() where T : class, IServiceClient
    {
        // Use reflection to create the derived type instance
        T instance = typeof(T).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof(string) }, null).Invoke(new object[] { endPointUrl }) as T;
    }
}

用法:

Channel channelService = factory.GetService<Channel>();

问题是我无法为工厂方法找到任何优雅的方式来实例化在方法中传递抽象基类型的派生类型。我唯一能想到的就是维护一个字典,其中包含抽象基础和相应的派生类之间的映射,但在我看来,这就像一种代码气味。任何人都可以提出更好的解决方案。

泛型工厂方法,用于从基类实例化派生类

虽然您确信只有一个实现,并假设它位于同一程序集中,但您可以通过反射找到它。例如:

Type implementationType = typeof(T).Assembly.GetTypes()
                                   .Where(t => t.IsSubclassOf(typeof(T))
                                   .Single();
return (T) Activator.CreateInstance(implementationType);

当然,出于性能原因,您可能希望将抽象类型缓存为具体类型。

如果有多个实现类,您需要考虑一个替代方案 - 一个选项是抽象类上的一个属性,说明使用哪个实现,如果可行的话。(如果没有更多的上下文,很难给出好的选择。

您似乎正在尝试重新发明 IOC 容器。 以Autofac为例。 您将向 IOC 容器注册具体类型,然后通过接口请求它们。