Sou*_*jji 2 c# design-patterns dependency-injection factory-pattern
我期待这个例子来了解工厂模式的使用.
我真的很喜欢这个领域,所以原谅我的愚蠢问题.
我的问题是我没有看到工厂模式的使用,它返回了我们可以在需要使用它时直接注入它的接口.
在上面的例子中,我会做这样的事情:
public class Program
{
// register the interfaces with DI container in a separate config class (Unity in this case)
private readonly IShippingStrategy _shippingStrategy;
public Program(IShippingStrategy shippingStrategy)
{
_shippingStrategy= shippingStrategy;
}
public int DoTheWork(Order order)
{
// assign properties just as an example
order.ShippingMethod = "Fedex";
order.OrderTotal = 90;
order.OrderWeight = 12;
order.OrderZipCode = 98109;
int shippingCost = _shippingStrategy.CalculateShippingCost(order);
return shippingCost;
}
}
Run Code Online (Sandbox Code Playgroud)
而不是注射工厂:
public class Program
{
// register the interfaces with DI container in a separate config class (Unity in this case)
private readonly IShippingStrategyFactory _shippingStrategyFactory;
public Program(IShippingStrategyFactory shippingStrategyFactory)
{
_shippingStrategyFactory = shippingStrategyFactory;
}
public int DoTheWork(Order order)
{
// assign properties just as an example
order.ShippingMethod = "Fedex";
order.OrderTotal = 90;
order.OrderWeight = 12;
order.OrderZipCode = 98109;
IShippingStrategy shippingStrategy = _shippingStrategyFactory.GetShippingStrategy(order);
int shippingCost = shippingStrategy.CalculateShippingCost(order);
return shippingCost;
}
}
Run Code Online (Sandbox Code Playgroud)
当我们可以直接将接口注入我们需要使用它的地方时,为什么要用它来创建一个工厂(从而增加一个额外的层)?
我想你不想只是另一篇关于工厂模式的文章,而是一个简短的综合答案.所以,我想专注于两件事.
最常见的是,你设置你的组合根,你基本上说...
"如果有人想要
IAnyService,他应该得到MyAnyServiceImplementation".
这是针对您的应用程序修复的.设置完成后,您的依赖项注入容器将为您注册的类实例提供服务,但您不应尝试再次重新配置该容器.这对于启动灵活性来说是完美的,例如,通过应用程序的配置注册数据访问组件的实现.说......
"如果有人想要
IUserRepository,他应该得到MsSqlUserRepository因为我们正在使用MSSQL服务器".
当然,拥有"不可变"组合根限制了根据应用程序状态在运行时选择实现的可能性.
相反,您可以注入一个类,该类决定当前状态选择哪个服务实现.数据验证是该模式的典型方案,因为系统上的不同实体可能存在不同的规则.这里的流行语是"规则模式"或"策略模式".
想象一个长期存在的类实例,如视图(用户界面)或附加到它的任何类(如视图模型或控制器).只要用户在视图上处于活动状态,该类就会处于活动状态.例如,通过将类实例注入视图控制器的构造函数,只要视图存在,就可以保存它的活动实例.
假设您想使用数据存储库连接到数据库.这些数据库访问调用应该很短,并且您不希望长时间保持连接打开.使用存储库工厂,您可以非常精确地控制生命周期,并确保在使用该类后将其删除:
using (var repository = new _factory.CreateRepository(...))
{
return repository.GetAnything();
}
Run Code Online (Sandbox Code Playgroud)
有了这个,一个非常轻量级的类 - 工厂 - 只要视图控制器存在就会被注入并生存.沉重的阶级 - 连接事物 - 不应该长寿,只是在需要时创建.
事实上,如果不需要加载数据(例如,由于前期缓存命中),很可能根本没有实例化存储库.如果您直接注入存储库,则可以保证在每种情况下都有一个长生存实例存在于内存中.