2016-01-23 60 views
1

比方说,我有一个实现以下接口下面的类:SimpleInjector:具有多个接口的类批量注册

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

我有两个其他类,如下列:

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

class ImportB { 
    public ImportB(IInterface<MyClassA>) {} 
} 
  • 我希望ImportA能够在我的程序集中注入执行IInterface的每个类。
  • 我想用ImportB注入一个IInterface<MyClassA>的实例。
  • 我希望两个方法的具体类MyClassA的实例是相同的(生命期:单身人士)。

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

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

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

UPDATE 1: 我正在寻找一种自动化方法。我有很多课程需要注册,不想亲自去做。这是一个不同的例子。下面的注册示例不起作用。

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为切入点,应该是暂时与自动化一个失败。 其他所有内容都应该是singleton,以便在ImportA中修改MyClassA时,该值将在MyClassB中拾取。

回答

3

要做到这一点的方法是手动创建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); 
} 
+0

我不能得到这个工作。我已经用更多信息更新了我的问题。 –

+0

@RabidPenguin:对不起。我错过了通用接口不应该被注册为集合的事实。我更新了我的问题。 – Steven

+0

_registration.ServiceType_不存在。你的意思是_registration.ImplementationType_?这似乎工作。那么当我做一个container.GetInstance(typeof(ImportA)),我的生活方式是ImportA(瞬态)> IEnumerable(IInterface)(Singleton)> IInterface (Singleton)?我不需要注册ImportA,对吧? –

相关问题