Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/265.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 简单喷油器喷油量可计量<;Func<;T>&燃气轮机;_C#_Dependency Injection_Expression Trees_Simple Injector - Fatal编程技术网

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注册了它们。