Generic Factory method to instantiate a derived class from the base class

不羁岁月 提交于 2021-02-07 20:02:14

问题


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.


回答1:


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.)




回答2:


You appear to be attempting to reinvent an IOC container. Take a look at Autofac for example. You would register your concrete types with the IOC container and then request them by interface.



来源:https://stackoverflow.com/questions/10723967/generic-factory-method-to-instantiate-a-derived-class-from-the-base-class

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!