在SimpleInjector documentation它是說:SimpleInjector意外行爲
簡單的注射器保留那些從注入
IEnumerable<T>
,ICollection<T>
,IList<T>
,IReadOnlyCollection<T>
和IReadOnlyList<T>
實例返回 實例的生活方式。實際上,您應該不會將注入的IEnumerable<T>
看作 實例的集合;你應該認爲它是一個實例流。簡單 噴油器將始終注入每次 你迭代IEnumerable<T>
,對各個組成部分相同的流(在IEnumerable<T>
或ICollection<T>
本身是一個單)和參考, 容器被要求解決基於生活方式的實例的 該組件。
看完這個我預期,我已經註冊的所有IFoo
和IFoo<T>
爲單身後,IEnumerable<IFoo>
將單本身,它枚舉總是會導致相同的對象。
但這段代碼不喜歡的工作:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using SimpleInjector;
class Program
{
interface IFoo{}
interface IFoo<T> : IFoo{}
class Foo : IFoo<Foo>{}
class Consumer1
{
public IFoo<Foo> FooInstance { get; }
public Consumer1(IFoo<Foo> fooInstance){FooInstance = fooInstance;}
}
class Consumer2
{
public IFoo<Foo> FooInstance { get; }
public Consumer2(IFoo<Foo> fooInstance){FooInstance = fooInstance;}
}
class Consumer3
{
public IEnumerable<IFoo> FooIntances { get; }
public Consumer3(IEnumerable<IFoo> fooIntances){FooIntances = fooIntances;}
}
static void Main(string[] args)
{
var cont = new Container();
var types = Assembly.GetExecutingAssembly()
.GetTypes()
.Where(x =>
typeof(IFoo<>).IsAssignableFrom(x) ||
typeof(IFoo).IsAssignableFrom(x))
.Where(x => !x.IsInterface);
foreach (var type in types)
{
var genericFoo = type.GetInterfaces().Single(x=>x.IsGenericType);
var genericArgs = genericFoo.GenericTypeArguments;
var closedGenericFoo = typeof(IFoo<>).MakeGenericType(genericArgs);
var reg = Lifestyle.Singleton.CreateRegistration(type, cont);
cont.AddRegistration(closedGenericFoo, reg);
cont.AddRegistration(typeof(IFoo), reg);
}
cont.RegisterCollection<IFoo>(new[] {Assembly.GetExecutingAssembly()});
var cons1 = cont.GetInstance<Consumer1>();
var cons2 = cont.GetInstance<Consumer2>();
var cons3_1 = cont.GetInstance<Consumer3>();
var cons3_2 = cont.GetInstance<Consumer3>();
// Expected: true | Actually: true
Console.WriteLine($"cons1.FooInstance == cons2.FooInstance : {cons1.FooInstance == cons2.FooInstance}");
// Expected: true | Actually: true
Console.WriteLine($"cons3_1.FooInstances == cons3_2.FooInstances : {cons3_1.FooIntances == cons3_2.FooIntances}");
// Expected: true | Actually: false
Console.WriteLine($"cons3_1.FooIntances.First() == cons1.FooInstance : {cons3_1.FooIntances.First() == cons1.FooInstance}");
// Expected: true | Actually: false
Console.WriteLine($"cons3_1.FooIntances.First() == cons3_2.FooIntances.First() : {cons3_1.FooIntances.First() == cons3_2.FooIntances.First()}");
Console.ReadKey();
}
}
我想要實現:註冊到兩個IFoo<Foo>
和 IFoo
(部分
- 單
Foo
實施作品) - 單一碼流
IFoo
這是IEnumerable<IFoo>
(它的工作原理) - 的
IEnumerable
迭代上述應該給我相同的Foo
執行(不工作)
這可能嗎?
請致電'Container.Verify()'在註冊階段的結束。這將導致一個例外,解釋爲什麼你的期望沒有得到滿足。 – Steven
@Steven它不:)它說我有3個'Foo'的註冊:1)單身'IFoo',2)單身'IFOO',和3)瞬變'IFoo'。第三個從哪裏冒出來。它解釋了爲什麼'IEnumerable '每次創建新的'IFoo',但它不能解釋我怎樣才能避免'IFoo'的臨時註冊 –
Szer