gpt4 book ai didi

c# - 简单注入(inject)器 : batch registration of classes with multiple interfaces

转载 作者:行者123 更新时间:2023-11-30 14:51:15 26 4
gpt4 key购买 nike

假设我有以下实现以下接口(interface)的类:

class MyClassA : IInterface<MyClassA>, IInterface
class MyClassB : IInterface<MyClassB>, IInterface

我还有另外两个类如下:

class ImportA {
public ImportA(IEnumerable<IInterface>) {}
}

class ImportB {
public ImportB(IInterface<MyClassA>) {}
}
  • 我希望将 ImportA 注入(inject)每个实现 IInterface 的类中在我的集会中。
  • 我希望 ImportB 只注入(inject) IInterface<MyClassA> 的一个实例.
  • 我希望两种方法中具体类 MyClassA 的实例相同(LifeTime:Singleton)。

我不知道如何让它与 Simple Injector 一起工作。我试过了 RegisterCollectionhttps://simpleinjector.readthedocs.org/en/latest/howto.html#register-multiple-interfaces-with-the-same-implementation

我最接近的是收到一个错误,说一个类导入为 Singleton,另一个类导入为 Transient。

我已经尝试将所有 LifeStyles 更改为 Singleton 并将配置默认设置为 Singleton,但无济于事。

更新 1:我正在寻找一种自动化的方法。我有很多类(class)要注册,不想手动注册。这是一个不同的示例。以下注册示例无效。自动化失败:

An exception of type 'SimpleInjector.ActivationException' occurred in  
SimpleInjector.dll but was not handled in user code

Additional information: The constructor of type MyClassB contains the
parameter with name 'myClassA' and type IInterface<MyClassA> that is not
registered. Please ensure IInterface<MyClassA> is registered, or change the
constructor of MyClassB. There is, however, a registration for
IEnumerable<IInterface<MyClassA>>; Did you mean to depend on
IEnumerable<IInterface<MyClassA>>?

这是我当前的代码:

public interface IInterface {
string Value { get; set; }
}

public interface IInterface<T> : IInterface { }

public class MyClassA : IInterface<MyClassA> {
public string Value { get; set; }
}

public class MyClassB : IInterface<MyClassB> {
private IInterface<MyClassA> myClassA;

public MyClassB(IInterface<MyClassA> myClassA) {
this.myClassA = myClassA;
}

public string Value {
get { return this.myClassA.Value; }
set { this.myClassA.Value = value; }
}
}

public class ImportA {
public ImportA(IEnumerable<IInterface> imports) {
// fails on this line
var a = imports.SingleOrDefault(i => i is IInterface<MyClassA>);
a.Value = "test";

var b = imports.SingleOrDefault(i => i is IInterface<MyClassB>);

// should output the value of "test";
Console.WriteLine(b.Value);
Console.ReadKey();
}
}

...
static void Main() {
var container = new Container();

var types = container.GetTypesToRegister(
typeof(IInterface<>), new[] { typeof(IInterface<>).Assembly });

var registrations = (
from type in types
select Lifestyle.Singleton.CreateRegistration(type, type, container))
.ToArray();

container.RegisterCollection<IInterface>(registrations);
container.RegisterCollection(typeof(IInterface<>), registrations);

var a = container.GetInstance(typeof(ImportA));
}

ImportA 是入口点,应该是 Transient。其他一切都应该是单例的,这样当 MyClassA 在 ImportA 中被修改时,值在 MyClassB 中被拾取。

最佳答案

做到这一点的方法是创建 Registration手动实例并使用它们注册两个单独的集合。示例:

var a = Lifestyle.Singleton.CreateRegistration<MyClassA>(container);
var b = Lifestyle.Singleton.CreateRegistration<MyClassB>(container);

container.RegisterCollection<IInterface>(new[] { a, b });

container.AddRegistration(typeof(IInterface<MyClassA>), a);
container.AddRegistration(typeof(IInterface<MyClassB>), b);

这将确保在两个集合中使用相同的单个实例。如果一个类实现了 IInterface<T> 的多个通用版本,相同的单个实例甚至会在 IInterface<T> 的不同集合中重复使用.

如果您想要更自动化的方法,您可以这样做:

var types = container.GetTypesToRegister(typeof(IInterface<>), assemblies);

// NOTE: The ToArray() call is crucial to prevent torn lifestyles.
var registrations = (
from type in types
select Lifestyle.Singleton.CreateRegistration(type, type, container))
.ToArray();

container.RegisterCollection<IInterface>(registrations);

foreach (var registration in registrations) {
container.AddRegistration(
typeof(IInterface<>).MakeGenericType(registration.ImplementationType),
registration);
}

关于c# - 简单注入(inject)器 : batch registration of classes with multiple interfaces,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34959791/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com