C# Unity Container Constructor Injection transient lifetime manager 同一实例服务
C# Unity Container Constructor Injection transient lifetime manager same instance served
问题: 我有一些 XSD 生成的模型很复杂,我想让 Unity 构建它们。 classes 中有许多 classes 的嵌套和数组,我不想更新它们。
如果我这样做并使用构造函数注入,似乎我每次使用生成 class 时都不会获得新模型。我填充的列表包含所有记录都引用同一实例的记录。
这个例子简化了问题:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using Unity;
namespace sandbox
{
public class Test
{
private GetTestRec _getTestRec;
public Test(GetTestRec getTestRec)
{
_getTestRec = getTestRec;
}
public void RunMe()
{
var mylist = new List<TestModel>();
var InList = new List<StructIn>();
InList.Add(new StructIn() { Name = "asd", Amount = 5.55F });
InList.Add(new StructIn() { Name = "lkj", Amount = 1.00F });
foreach (var item in InList)
{
mylist.Add(_getTestRec.Get(item));
}
foreach (var item in mylist)
{
Console.WriteLine($"{item.Name} {item.Amount}" );
}
}
}
public class GetTestRec
{
private TestModel _testModel;
public GetTestRec(TestModel testModel)
{
//_testModel = testModel;
}
public TestModel Get(StructIn structIn)
{
_testModel = UnityConfig.Container.Resolve<TestModel>();
_testModel.Name = structIn.Name;
_testModel.Amount = structIn.Amount;
return _testModel;
}
}
public class TestModel
{
public TestModel()
{ }
public string Name { get; set; }
public float Amount { get; set; }
}
public struct StructIn
{
public string Name;
public float Amount;
}
}
在上面的代码中,TestModel 被显式解析。如果我解析 GetTestRec 并执行 RunMe()...
var testThis = UnityConfig.Container.Resolve<Test>();
testThis.RunMe();
您可以看到它正确地生成了两个 TestModel 实例并将它们添加到列表中
asd 5.55
lkj 1
但是如果我注释掉显式解析并改为通过构造函数注入 TestModel...
public class GetTestRec
{
private TestModel _testModel;
public GetTestRec(TestModel testModel)
{
_testModel = testModel;
}
public TestModel Get(StructIn structIn)
{
//_testModel = UnityConfig.Container.Resolve<TestModel>();
_testModel.Name = structIn.Name;
_testModel.Amount = structIn.Amount;
return _testModel;
}
}
您可以看到它只使用了一个 TestClass 实例,并且列表中的所有记录都指向同一个实例
lkj 1
lkj 1
如何使用构造函数注入每次都获取一个新的实例?默认的瞬态生命周期表示它在每次解析时都会获得一个新实例,如果我调用 resolve 那么我确实会获得一个新实例。但是,使用构造函数我不相信 resolve 被调用,因为它之前已经被解析过。
这里最好的方向是什么?我应该在什么地方寻找带有 Unity 的工厂模式?
假设您在每次调用 TestModel Get
时都希望 return 新模型(实质上是用某种 DI 友好代码替换 new TestModel
。
依赖工厂方法(如Func<TestModel>
)根据需要创建它们。使用 Unity,您无需添加任何特殊注册即可使其正常工作 - 它始终同时注册 T
和 Func<T>
(即 container => container.Resolve<T>()
)。对于其他容器,您可能需要手动注册它甚至创建工厂接口。
public class GetTestRec
{
private Func<TestModel> _testModelFactory;
public GetTestRec(Func<TestModel> testModelFactory)
{
_testModelFactory = testModelFactory;
}
public TestModel Get(StructIn structIn)
{
TestModel newModel = _testModelFactory();
newModel.Name = structIn.Name;
newModel.Amount = structIn.Amount;
return newModel;
}
}
问题: 我有一些 XSD 生成的模型很复杂,我想让 Unity 构建它们。 classes 中有许多 classes 的嵌套和数组,我不想更新它们。
如果我这样做并使用构造函数注入,似乎我每次使用生成 class 时都不会获得新模型。我填充的列表包含所有记录都引用同一实例的记录。
这个例子简化了问题:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using Unity;
namespace sandbox
{
public class Test
{
private GetTestRec _getTestRec;
public Test(GetTestRec getTestRec)
{
_getTestRec = getTestRec;
}
public void RunMe()
{
var mylist = new List<TestModel>();
var InList = new List<StructIn>();
InList.Add(new StructIn() { Name = "asd", Amount = 5.55F });
InList.Add(new StructIn() { Name = "lkj", Amount = 1.00F });
foreach (var item in InList)
{
mylist.Add(_getTestRec.Get(item));
}
foreach (var item in mylist)
{
Console.WriteLine($"{item.Name} {item.Amount}" );
}
}
}
public class GetTestRec
{
private TestModel _testModel;
public GetTestRec(TestModel testModel)
{
//_testModel = testModel;
}
public TestModel Get(StructIn structIn)
{
_testModel = UnityConfig.Container.Resolve<TestModel>();
_testModel.Name = structIn.Name;
_testModel.Amount = structIn.Amount;
return _testModel;
}
}
public class TestModel
{
public TestModel()
{ }
public string Name { get; set; }
public float Amount { get; set; }
}
public struct StructIn
{
public string Name;
public float Amount;
}
}
在上面的代码中,TestModel 被显式解析。如果我解析 GetTestRec 并执行 RunMe()...
var testThis = UnityConfig.Container.Resolve<Test>();
testThis.RunMe();
您可以看到它正确地生成了两个 TestModel 实例并将它们添加到列表中
asd 5.55
lkj 1
但是如果我注释掉显式解析并改为通过构造函数注入 TestModel...
public class GetTestRec
{
private TestModel _testModel;
public GetTestRec(TestModel testModel)
{
_testModel = testModel;
}
public TestModel Get(StructIn structIn)
{
//_testModel = UnityConfig.Container.Resolve<TestModel>();
_testModel.Name = structIn.Name;
_testModel.Amount = structIn.Amount;
return _testModel;
}
}
您可以看到它只使用了一个 TestClass 实例,并且列表中的所有记录都指向同一个实例
lkj 1
lkj 1
如何使用构造函数注入每次都获取一个新的实例?默认的瞬态生命周期表示它在每次解析时都会获得一个新实例,如果我调用 resolve 那么我确实会获得一个新实例。但是,使用构造函数我不相信 resolve 被调用,因为它之前已经被解析过。
这里最好的方向是什么?我应该在什么地方寻找带有 Unity 的工厂模式?
假设您在每次调用 TestModel Get
时都希望 return 新模型(实质上是用某种 DI 友好代码替换 new TestModel
。
依赖工厂方法(如Func<TestModel>
)根据需要创建它们。使用 Unity,您无需添加任何特殊注册即可使其正常工作 - 它始终同时注册 T
和 Func<T>
(即 container => container.Resolve<T>()
)。对于其他容器,您可能需要手动注册它甚至创建工厂接口。
public class GetTestRec
{
private Func<TestModel> _testModelFactory;
public GetTestRec(Func<TestModel> testModelFactory)
{
_testModelFactory = testModelFactory;
}
public TestModel Get(StructIn structIn)
{
TestModel newModel = _testModelFactory();
newModel.Name = structIn.Name;
newModel.Amount = structIn.Amount;
return newModel;
}
}