我们正在提供一组Entity和Consumer类。调用XConsumer会返回一个XEntity,而调用YConsumer会返回一个YEntity,依此类推。使用相同类型的参数的Consumer类的API是相同的。 Consumer和Entity类不从基类继承,也不实现接口。我想要实现的是通常调用返回特定类型的所需实体的工厂。我目前的实现如下:
static class Factory<TConsumer> where TConsumer : new()
{
static dynamic Consume(Document document, out List<Error> errors)
{
// Common code before calling any consumer goes here
Stream stream = document.Stream;
dynamic consumer = new TConsumer();
return consumer.Consume(stream, out errors);
}
}
我的调用代码如此
XEntity entity = Factory<XConsumer>.Consume(document, out errors);
注意我只负责Factory类和调用代码,不允许修改Entity和Consumer类。有没有办法让这更好,最好不使用动态?
答案 0 :(得分:1)
避免反思的一种方法是使用Adapter pattern.
基本上,您所做的是创建一个interface
,其中包含consumer
类的常用方法和属性,并为实现此接口的每个consumer
创建一个包装类。 / p>
通过这种方式,您可以在不使用dynamic
或reflection
的情况下实施您的方法,并保持其安全类型。
当然,缺点是你必须编写(并维护)比目前更多的代码。
答案 1 :(得分:0)
理想情况下,您需要更改实体类,以便它们都实现接口,例如IEntity。工厂应根据某些标准选择消费者,而不是知道您要使用哪个消费者。您可以根据所需的wntiry返回类型做出此决定。
例如:
// you don't necessarily need this interface but it allows a meaningful
// constraint if you apply it to your 'entity' classes. If you can't apply
// this interface to the entity classes then remove the constraints below
public interface IEntity
{
// things it does
}
public class XEntity : IEntity
{
}
public class YEntity : IEntity
{
}
public interface IConsumer<TEntity> where TEntity : IEntity // remove constraint if required
{
TEntity Consume(Stream stream, out List<Error> errors);
}
public class XConsumer : IConsumer<XEntity>
{
public XEntity Consume(Stream stream, out List<Error> errors);
{
// something
}
}
public class YConsumer : IConsumer<YEntity>
{
public YEntity Consume(Stream stream, out List<Error> errors);
{
// something
}
}
public static class ConsumerFactory
{
// this will now create a consumer instance based on the entity type
public static IConsumer<TEntity> Create<TEntity>() where TEntity : IEntity // remove constraint if required
{
if (typeof(TEntity) == typeof(XEntity))
return new XConsumer;
if (typeof(TEntity) == typeof(YEntity))
return new YConsumer;
throw new Exception("Unsupported type");
}
public static TEntity Consume<TEntity>(Stream stream, out List<Error> errors) where TEntity : IEntity // remove constraint if required
{
return Create<TEntity>().Consume(stream, out errors);
}
}
用法:
XEntity x = ConsumerFactory.Consume<XEntity>(document, out errors);
YEntity y = ConsumerFactory.Consume<YEntity>(document, out errors);
答案 2 :(得分:0)
没有反映不是我想要的。我将你的回答标记为答案,但我会坚持自己的实施。最初我以为我发布这个问题以防我错过了什么