简体   繁体   English

Generic Factory方法,用于从基类实例化派生类

[英]Generic Factory method to instantiate a derived class from the base class

I am in the process of creating a factory method which uses a generic abstract type parameter to return the instance of the concrete derived type using reflection. 我正在创建一个工厂方法,该方法使用通用抽象类型参数来使用反射返回具体派生类型的实例。 For eg. 例如。

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;
    }
}

Usage: 用法:

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

The issue is that I cannot figure out any elegant way for the factory method to instantiate the derived type being passed the abstract base type in the method. 问题是我无法找出工厂方法的任何优雅方式来实例化在方法中传递抽象基类型的派生类型。 The only thing I can come up with is to maintain a Dictionary containing the map between the abstract base and the corresponding derived class but this seems to me like a code smell. 我唯一能想到的是维护一个包含抽象基类和相应派生类之间映射的字典,但这在我看来就像代码味道。 Can anybody suggest a better solution. 任何人都可以提出更好的解决方案。

While you're confident of there being only one implementation, and assuming it's within the same assembly, you could find it via reflection. 虽然你确信只有一个实现,并假设它在同一个程序集中,你可以通过反射找到它。 For example: 例如:

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

Of course for performance reasons you may well want to have a cache of abstract type to concrete type. 当然,出于性能原因,您可能希望将抽象类型的缓存设置为具体类型。

If there are multiple implementation classes, you'll need to think of an alternative - one option would be an attribute on the abstract class saying which implementation to use, if that's feasible. 如果有多个实现类,则需要考虑另一种选择 - 一个选项是抽象类的一个属性,说明要使用哪个实现,如果可行的话。 (It's hard to give good options without more context.) (如果没有更多的背景,很难给出好的选择。)

You appear to be attempting to reinvent an IOC container. 您似乎正在尝试重新发明IOC容器。 Take a look at Autofac for example. Autofac为例。 You would register your concrete types with the IOC container and then request them by interface. 您将使用IOC容器注册具体类型,然后通过接口请求它们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM