Generics Autofac-解析通用接口
我在解决实现泛型接口的类型时遇到问题。以下是事件类、泛型接口和实现泛型接口的类Generics Autofac-解析通用接口,generics,asp.net-core,autofac,Generics,Asp.net Core,Autofac,我在解决实现泛型接口的类型时遇到问题。以下是事件类、泛型接口和实现泛型接口的类 public class ExampleEvent : IDomainEvent { public ExampleEvent() { DateTimeEventOccurred = DateTime.Now; } public DateTime DateTimeEventOccurred { get; private set; } } public interfac
public class ExampleEvent : IDomainEvent
{
public ExampleEvent()
{
DateTimeEventOccurred = DateTime.Now;
}
public DateTime DateTimeEventOccurred { get; private set; }
}
public interface IHandle<T> where T : IDomainEvent
{
void Handle(T args);
}
public class ExampleEventHandler : IHandle<ExampleEvent>
{
public ExampleEventHandler()
{
}
public void Handle(ExampleEvent args)
{
//Handle Event
}
}
鉴于这将失败:
foreach (var domainEvent in entity.DeferredEvents.ToArray())
{
_handler.Raise(domainEvent);
}
我对我的实体的收藏如下:
public List<IDomainEvent> DeferredEvents { get; set; }
公共列表延迟事件{get;set;}
我仍然不确定如何解决此问题。此问题是由您调用
\u handler.Raise造成的。正如您所说,延迟事件
存储在列表
中。这会导致失败的代码如下所示:
foreach (var domainEvent in entity.DeferredEvents.ToArray())
{
_handler.Raise<IDomainEvent>(domainEvent);
}
public void Raise<IDomainEvent>(IDomainEvent args) where T : IDomainEvent
{
foreach (var handler in _container.Resolve<IEnumerable<IHandle<IDomainEvent>>>())
{
handler.Handle(args);
}
}
public void Raise(IDomainEvent args)
{
foreach (var handler in _container.Resolve<IEnumerable<IHandle<IDomainEvent>>>())
{
handler.Handle(args);
}
}
查看您的注册,没有实现IHandle
接口的事件处理程序。只有一个实现了IHandle
接口。因此,调用resolveIEnumerable
将不会产生任何结果
更新
那么在这种情况下,是否就没有办法通过接口或基类的集合进行循环?在上述假设下,Autofac将基于接口或基类而不是派生类型解析实例,但我在许多域事件示例中都看到了同样的方法
Autofac根据注册进行解析。在您的示例中,ExampleEventHandler
实现了IHandle
,并注册为IHandle
,因此如果解析IEnumerable
,则不会返回ExampleEventHandler
的实例
但是,我不认为注册是错误的,我认为错误在于调用Raise
方法的方式。Raise
方法有一个未使用的泛型类型参数T
(至少在您的示例中未使用)。在您的示例中,Raise
方法实际上如下所示:
foreach (var domainEvent in entity.DeferredEvents.ToArray())
{
_handler.Raise<IDomainEvent>(domainEvent);
}
public void Raise<IDomainEvent>(IDomainEvent args) where T : IDomainEvent
{
foreach (var handler in _container.Resolve<IEnumerable<IHandle<IDomainEvent>>>())
{
handler.Handle(args);
}
}
public void Raise(IDomainEvent args)
{
foreach (var handler in _container.Resolve<IEnumerable<IHandle<IDomainEvent>>>())
{
handler.Handle(args);
}
}
或者,您可以将所有处理程序更改为实现IHandle>
,如果事件类型与预期类型不匹配,则不执行任何操作:
public class ExampleEventHandler : IHandle<IDomainEvent>
{
public ExampleEventHandler()
{
}
public void Handle(IDomainEvent args)
{
if (!(args is ExampleEvent))
return;
//Handle Event
}
}
公共类ExampleEventHandler:IHandle
{
public ExampleEventHandler()
{
}
公共无效句柄(IDomainEvent参数)
{
如果(!(args是ExampleEvent))
返回;
//处理事件
}
}
那么在这种情况下,是否就没有办法在接口或基类的集合中循环?在上述假设下,Autofac将基于接口或基类而不是派生类型解析实例,但我在许多域事件示例中都看到了同样的方法。
public class ExampleEventHandler : IHandle<IDomainEvent>
{
public ExampleEventHandler()
{
}
public void Handle(IDomainEvent args)
{
if (!(args is ExampleEvent))
return;
//Handle Event
}
}