与一次性对象一起注入和使用(重置对象属性)
本文关键字:对象 属性 一次性 一起 注入 | 更新日期: 2023-09-27 18:30:35
在引入依赖注入之前,我有一个类,看起来像这样:
public class Widget
{
public Widget Create()
{
using (DataProvider dataProvider = new DataProvder())
{
dataProvider.AddInput("name", name);
dataProvider.AddInput("path", path);
dataProvider.AddInput("dateCreated", DateTime.UtcNow);
using (var reader = _dataProvider.ExecuteReader("usp_widget_create"))
{
reader.Read();
return new Widget(reader);
}
}
}
}
然后我使用 Ninject 引入了依赖关系注入,我的类现在看起来像这样,所以我不会创建对 DataProvider 类的依赖关系。
public class Widget
{
IDataProvider _dataProvider;
public Widget(IDataProvider dataProvider)
{
_dataProvider = dataProvider;
}
public Widget Create()
{
_dataProvider.AddInput("name", name);
_dataProvider.AddInput("path", path);
_dataProvider.AddInput("dateCreated", DateTime.UtcNow);
using (var reader = _dataProvider.ExecuteReader("usp_widget_create"))
{
reader.Read();
return new Widget(reader);
}
}
}
新类的问题在于,第一,数据提供程序不会被释放,第二,数据提供程序的属性不会被重置。因此,如果我从同一对象调用 Create 两次,它将复制参数并引发异常。我知道我可以通过清除参数来明确解决第二个问题,但我觉得必须有一种更通用的方法,我错过了一些东西。
这种情况应该如何解决?
您非常想使用的模式是具有抽象工厂模式的依赖注入。此工厂模式允许您在需要时动态创建实例。这样做是很常见的事情。
定义允许您创建提供实例的工厂。
public interface IProviderFactory
{
T Create<T>();
}
实现可以很简单,如下所示。
public class ProviderFactory : IProviderFactory
{
private readonly IKernel _kernel;
public ProviderFactory(IKernel kernel)
{
_kernel = kernel;
}
public T Create<T>()
{
var instance = _kernel.Get<T>();
return instance;
}
}
现在更改您的小部件以接受工厂而不是 IDataProvider
public class Widget
{
readonly IProviderFactory _factory;
public Widget(IProviderFactory factory)
{
_factory = factory;
}
public Widget Create()
{
var provider = _factory.Create<IDataProvider>();
provider.AddInput("name", "name");
provider.AddInput("path", "path");
provider.AddInput("dateCreated", DateTime.UtcNow);
//.....
}
}
请注意,每次调用 Create() 都会解析 IDataProvider 的新实例。
VaR 提供程序 = _factory。创建();
内核注册如下所示。
using (IKernel Kernel = new StandardKernel())
{
Kernel.Bind<IDataProvider>().To<DataProvider>();
Kernel.Bind<IProviderFactory>()
.To<ProviderFactory>().WithConstructorArgument(typeof(IKernel), Kernel);
var widget = Kernel.Get<Widget>();
widget.Create();
widget.Create();
}
沿着线的东西应该为你提供可能的解决方案的方向。