C# 简单喷油器喷油量可计量<;Func<;T>&燃气轮机;
如何使用简单注入器注入C# 简单喷油器喷油量可计量<;Func<;T>&燃气轮机;,c#,dependency-injection,expression-trees,simple-injector,C#,Dependency Injection,Expression Trees,Simple Injector,如何使用简单注入器注入IEnumerable 为了添加一些上下文,我尝试创建所有知道如何处理一个特定事件的EventHandler。下面是我的容器注册: container.RegisterCollection(typeof(IHandleDomainEvent<>), AppDomain.CurrentDomain.GetAssemblies()); container.ResolveUnregisteredType += (o, args) => ResolveF
IEnumerable
为了添加一些上下文,我尝试创建所有知道如何处理一个特定事件的EventHandler。下面是我的容器注册:
container.RegisterCollection(typeof(IHandleDomainEvent<>),
AppDomain.CurrentDomain.GetAssemblies());
container.ResolveUnregisteredType += (o, args) => ResolveFuncOfT(o, args, container);
// Function
private static void ResolveFuncOfT(object s, UnregisteredTypeEventArgs e, Container container)
{
var type = e.UnregisteredServiceType;
if (!type.IsGenericType || type.GetGenericTypeDefinition() != typeof(Func<>)) return;
Type serviceType = type.GetGenericArguments().First();
InstanceProducer producer = container.GetRegistration(serviceType, true);
Type funcType = typeof(Func<>).MakeGenericType(serviceType);
var factoryDelegate = Expression.Lambda(funcType, producer.BuildExpression()).Compile();
e.Register(Expression.Constant(factoryDelegate));
}
container.RegisterCollection(类型为(IHandleDomainEvent),
AppDomain.CurrentDomain.GetAssemblys());
这里有两个类为同一事件实现了IHandleEvent
接口:
public class Reservation : IHandleDomainEvent<OrderConfirmed>{}
public class Order: IHandleDomainEvent<OrderConfirmed>{}
公共类保留:IHandleDomainEvent{}
公共类秩序:IHandleDomainEvent{}
因此,当我调用简单喷油器时:
var handlers = _container.GetAllInstances<Func<IHandleDomainEvent<OrderConfirmed>>>();
var handlers=\u container.GetAllInstances();
我想收到IEnumerable
为了澄清,我知道如果我打电话:
var handlers = _container.GetAllInstances<IHandleDomainEvent<OrderConfirmed>>();
var handlers=\u container.GetAllInstances();
我会得到一个IEnumerable
对于只有一个实现的接口,使用以下方式注册:
container.Register(typeof(IHandleDomainEvent<>),
AppDomain.CurrentDomain.GetAssemblies(), Lifestyle.Scoped);
container.Register(类型为(IHandleDomainEvent),
AppDomain.CurrentDomain.getAssemblys(),lifesture.Scoped);
并将以下ResolveUnregistedType添加到注册的末尾:
container.RegisterCollection(typeof(IHandleDomainEvent<>),
AppDomain.CurrentDomain.GetAssemblies());
container.ResolveUnregisteredType += (o, args) => ResolveFuncOfT(o, args, container);
// Function
private static void ResolveFuncOfT(object s, UnregisteredTypeEventArgs e, Container container)
{
var type = e.UnregisteredServiceType;
if (!type.IsGenericType || type.GetGenericTypeDefinition() != typeof(Func<>)) return;
Type serviceType = type.GetGenericArguments().First();
InstanceProducer producer = container.GetRegistration(serviceType, true);
Type funcType = typeof(Func<>).MakeGenericType(serviceType);
var factoryDelegate = Expression.Lambda(funcType, producer.BuildExpression()).Compile();
e.Register(Expression.Constant(factoryDelegate));
}
container.ResolveUnregistedType+=(o,args)=>ResolveFunsoft(o,args,container);
//作用
私有静态void ResolveFunSoft(对象s、未注册的TypeEventArgs e、容器)
{
var type=e.UnregisteredServiceType;
如果(!type.IsGenericType | | type.GetGenericTypeDefinition()!=typeof(Func))返回;
类型serviceType=Type.GetGenericArguments().First();
InstanceProducer producer=container.GetRegistration(serviceType,true);
Type funcType=typeof(Func).MakeGenericType(serviceType);
var factoryDelegate=Expression.Lambda(funcType,producer.BuildExpression()).Compile();
e、 寄存器(表达式常数(factoryDelegate));
}
将允许呼叫:
var handler = _container.GetInstance<Func<IHandleDomainEvent<TEvent>>>();
var handler=\u container.GetInstance();
这就是简单注入器的美妙之处:您永远不必解析IEnumerable
,因为任何由简单注入器解析的IEnumerable
都已作为流运行
这意味着在解析IEnumerable
时,流中的任何元素都不会被解析。它们仅在迭代可枚举项时得到解析,并逐个解析
迭代流时,元素将根据其生活方式进行解析。这意味着,当集合中的元素是瞬态时,迭代流两次将导致创建新的瞬态实例
例如:
// Only resolves the enumerable, not the contained handlers.
// This enumerable itself is a singleton, you can reference it forever.
var collection = container.GetInstances<IEventHandler<OrderConfirmed>>();
// Calls back into the container to get the first element, but nothing more
var first = collection.First();
// Since the stream that Simple Injector returns is a IList<T>, getting the last
// element is an O(1) operation, meaning that only the last element is resolved;
// not the complete collection.
var last = collection.Last();
// Calling .ToArray(), however, will obviously resolve all registrations that are
// part of the collection.
var all = collection.ToArray();
// Iterating a stream will always call back into the container, which ensures
// that the stream adheres to the elements lifestyles. Transients will be
// created on each iteration, while singletons will only be created once.
container.Register<Apple>(Lifestyle.Transient);
container.Register<Banana>(Lifestyle.Singleton);
container.RegisterCollection<IFruit>(typeof(Apple), typeof(Banana));
var fruits = container.GetAllInstances<IFruit>();
Assert.AreNotSame(fruits.First(), fruits.First());
Assert.AreSame(fruits.Last(), fruits.Last());
// Even other collection types such as IReadOnlyCollection<T> behave as streams
var col = container.GetInstance<IReadOnlyCollection<IEventHandler<OrderConfirmed>>();
// This gives you the possibility to get a particular item by its index.
var indexedItem = col[3];
//只解析可枚举项,而不解析包含的处理程序。
//这个可枚举项本身是一个单例,您可以永远引用它。
var collection=container.GetInstances();
//回调容器以获取第一个元素,但仅此而已
var first=collection.first();
//由于Simple Injector返回的流是IList,因此获取最后一个
//元素是一个O(1)操作,意味着只解析最后一个元素;
//不是完整的集合。
var last=collection.last();
//但是,调用.ToArray()显然会解决所有注册问题
//收藏的一部分。
var all=collection.ToArray();
//迭代流将始终回调到容器中,从而确保
//这条溪流依附于生活方式的元素。瞬变将是
//在每次迭代中创建,而单例将只创建一次。
集装箱。登记
不错!但是,我不是舒尔,它会帮助我。因为我需要simpleinjector在每次调用Func时返回一个实例。因此,如果我调用(在您的示例中)collection.First()两次,两个实例将是相同的。最后,我看到的唯一出路是创建一个类来打开一个新的作用域,并在这个作用域内实例化类T。因此,每次我调用它时,都在一个新的作用域内实例化。如果每次首先调用时都需要一个新的实例,请确保hsndlers注册为Transient。您当前似乎已使用作用域或Singleton注册了它们。