我正在创建一个工厂方法,该方法使用通用抽象类型参数来使用反射返回具体派生类型的实例。例如。
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>();
问题是我无法找出工厂方法的任何优雅方式来实例化在方法中传递抽象基类型的派生类型。我唯一能想到的是维护一个包含抽象基类和相应派生类之间映射的字典,但这在我看来就像代码味道。任何人都可以提出更好的解决方案。
答案 0 :(得分:4)
虽然你确信只有一个实现,并假设它在同一个程序集中,你可以通过反射找到它。例如:
Type implementationType = typeof(T).Assembly.GetTypes()
.Where(t => t.IsSubclassOf(typeof(T))
.Single();
return (T) Activator.CreateInstance(implementationType);
当然,出于性能原因,您可能希望将抽象类型的缓存设置为具体类型。
如果有多个实现类,则需要考虑另一种选择 - 一个选项是抽象类的一个属性,说明要使用哪个实现,如果可行的话。 (如果没有更多的背景,很难给出好的选择。)
答案 1 :(得分:1)
您似乎正在尝试重新发明IOC容器。例如,查看Autofac。您可以使用IOC容器注册具体类型,然后通过接口请求它们。