pgh*_*ech 3 c# factory-pattern
我在我的项目中实现了一个工厂,最近建议我在我的类上使用属性,以便工厂可以确定要实例化和传回的类.我是开发世界的新手,并试图严格遵循松散耦合的规则,我想知道是否依赖"钩子"(作为属性)违背了这一点?
装饰工厂的产品类可以使开发更容易,这是我有时会做的事情.当必须基于存储在数据库中的唯一标识符创建产品时,这尤其有用.必须在该唯一ID和产品类之间建立映射,并且使用属性使其非常清晰且可重用.除此之外,它允许您添加产品类,而无需更改工厂.
例如,您可以像这样装饰您的类:
[ProductAttribute(1)]
public class MyFirstProduct : IProduct
{
}
[ProductAttribute(2)]
public class MySecondProduct : IProduct
{
}
Run Code Online (Sandbox Code Playgroud)
你可以这样实现你的工厂:
public class ProductFactory : IProductFactory
{
private static Dictionary<int, Type> products =
new Dictionary<int, Type>();
static ProductFactory()
{
// Please note that this query is a bit simplistic. It doesn't
// handle error reporting.
var productsWithId =
from type in
Assembly.GetExecutingAssembly().GetTypes()
where typeof(IProduct).IsAssignableFrom(type)
where !type.IsAbstract && !type.IsInterface
let attributes = type.GetCustomAttributes(
typeof(ProductAttribute), false)
let attribute = attributes[0] as ProductAttribute
select new { type, attribute.Id };
products = productsWithId
.ToDictionary(p => p.Id, p => p.type);
}
public IProduct CreateInstanceById(int id)
{
Type productType = products[id];
return Activator.CreateInstance(productType) as IProduct;
}
}
Run Code Online (Sandbox Code Playgroud)
完成此操作后,您可以使用该工厂创建如下产品:
private IProductFactory factory;
public void SellProducts(IEnumerable<int> productIds)
{
IEnumerable<IProduct> products =
from productId in productIds
select factory.CreateInstanceById(productId);
foreach (var product in products)
{
product.Sell();
}
}
Run Code Online (Sandbox Code Playgroud)
我过去曾使用过这个概念,例如根据数据库标识符创建发票计算.该数据库包含每种发票类型的计算列表.实际计算是在C#类中定义的.