gpt4 book ai didi

c# - 自动注册通用接口(interface)的所有实现

转载 作者:太空狗 更新时间:2023-10-29 21:34:09 25 4
gpt4 key购买 nike

我当前的注册码:

Assembly web = Assembly.Load("MyAssembly");
types.AddRange(web.GetTypes());
//etc.

foreach (var theInterface in types.Where(t => t.IsInterface))
{
var assignableType = types.Where(t => theInterface.IsAssignableFrom(t) && t != theInterface);
foreach (var type in assignableType)
{
container.RegisterType(theInterface, type);
}
}

我的通用接口(interface)及其实现:

public interface IDomainEventHandler<in T>
{
void Handle(T message);
}

public class DomainEventHandler1 : IDomainEventHandler<PhilTest1>
{
public void Handle(PhilTest1 message)
{
throw new System.NotImplementedException();
}
}

public class DomainEventHandler2 : IDomainEventHandler<PhilTest2>
{
public void Handle(PhilTest2 message)
{
throw new System.NotImplementedException();
}
}

public class DomainEventHandler3 : IDomainEventHandler<PhilTest2>
{
public void Handle(PhilTest2 message)
{
throw new System.NotImplementedException();
}
}

public class PhilTest1
{

}

public class PhilTest2
{

}

这是我将如何解决的简化版本:

IEnumerable<IDomainEventHandler<PhilTest2>> listeners = Container.ResolveAll<IDomainEventHandler<PhilTest2>>();
IEnumerable<IDomainEventHandler<PhilTest1>> listeners2 = Container.ResolveAll<IDomainEventHandler<PhilTest1>>();

这不起作用——listeners 和 listeners2 在解析后都是空的。这并不意外。

在温莎,我可以这样做:

container.Register(AllTypes.FromAssemblyNamed("MyAssembly").BasedOn(typeof(IDomainEventHandler<>)).WithService.Base());

如何在 Unity 中注册 IDomainEventHandler 的所有实例?我希望保持现有的注册码不变(如果可能)。

最佳答案

有点痛苦,但我最终通过谷歌搜索和调试将其拼凑起来:

注册:

    IEnumerable<Type> handlers = types.Where(t => IsAssignableToGenericType(t, typeof(IDomainEventHandler<>)) && !t.IsInterface);

foreach (var handler in handlers)
{
container.AddNewExtension<OpenGenericExtension>()
.Configure<IOpenGenericExtension>()
.RegisterClosedImpl(typeof (IDomainEventHandler<>), handler);
}

IsAssignableToGenericType 方法:

    private static bool IsAssignableToGenericType(Type givenType, Type genericType)
{
var interfaceTypes = givenType.GetInterfaces();

foreach (var it in interfaceTypes)
{
if (it.IsGenericType && it.GetGenericTypeDefinition() == genericType)
return true;
}

if (givenType.IsGenericType && givenType.GetGenericTypeDefinition() == genericType)
return true;

Type baseType = givenType.BaseType;
if (baseType == null) return false;

return IsAssignableToGenericType(baseType, genericType);
}

还有扩展。请注意,如果我没有使用名称进行注册,则只有一种类型会保持注册状态。我相信这是设计使然?

public interface IOpenGenericExtension : IUnityContainerExtensionConfigurator
{
void RegisterClosedImpl(Type openGenericInterface, Type closedType);
}

public class OpenGenericExtension : UnityContainerExtension, IOpenGenericExtension
{
protected override void Initialize() {}

public void RegisterClosedImpl(Type openGenericInterface, Type closedType)
{
closedType.GetInterfaces().Where(x => x.IsGenericType)
.Where(x => x.GetGenericTypeDefinition() == openGenericInterface)
.ToList()
.ForEach(x => Container.RegisterType(x, closedType, closedType.Name));
}
}

关于c# - 自动注册通用接口(interface)的所有实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20148474/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com