不需要注册的 IoC 容器
IoC container that doesn't require registration
有这种事吗?
如果我需要做的只是将 IThing 解析为 Thing,为什么我还需要创建一个注册?我应该在 运行 时间内动态映射。我可以轻松地创建一个反射..但希望避免构建我自己的..
我正在以同样的方式解决。用反射很容易做到,不需要注册..
您正在寻找的是自动注册的概念。大多数容器允许您根据 约定 在程序集中注册类型,或者执行未注册的类型解析并为您找到缺失的类型。
例如,您可以搜索程序集并在启动期间注册所有符合约定的类型:
var container = new Container();
Assembly assembly = typeof(Thing).Assembly;
var mappings =
from type in assembly.GetExportedTypes()
let matchingInterface = "I" + type.Name
let service = type.GetInterfaces().FirstOrDefault(i => matchingInterface)
where service != null
select new { service, type };
foreach (var mapping in mappings)
{
// Register the type in the container
container.Register(mapping.service, mapping.type);
}
使用未注册的类型解析,您可以即时进行注册。如何做到这一点在很大程度上取决于您使用的容器。例如,对于 Simple Injector,这看起来如下:
var container = new Container();
Assembly assembly = typeof(Thing).Assembly;
container.ResolveUnregisteredType += (s, e)
{
Type service = e.UnregisteredServiceType;
if (service.IsInterface)
{
var types = (
from type in asssembly.GetExportedTypes()
where service.IsAssignableFrom(type)
where !type.IsAbstract
where service.Name == "I" + type.Name
select type)
.ToArray();
if (types.Length == 1)
{
e.Register(Lifestyle.Transient.CreateRegistration(types[0], container));
}
}
};
这两种方法都可以避免您不断更新容器配置。
有这种事吗? 如果我需要做的只是将 IThing 解析为 Thing,为什么我还需要创建一个注册?我应该在 运行 时间内动态映射。我可以轻松地创建一个反射..但希望避免构建我自己的..
我正在以同样的方式解决。用反射很容易做到,不需要注册..
您正在寻找的是自动注册的概念。大多数容器允许您根据 约定 在程序集中注册类型,或者执行未注册的类型解析并为您找到缺失的类型。
例如,您可以搜索程序集并在启动期间注册所有符合约定的类型:
var container = new Container();
Assembly assembly = typeof(Thing).Assembly;
var mappings =
from type in assembly.GetExportedTypes()
let matchingInterface = "I" + type.Name
let service = type.GetInterfaces().FirstOrDefault(i => matchingInterface)
where service != null
select new { service, type };
foreach (var mapping in mappings)
{
// Register the type in the container
container.Register(mapping.service, mapping.type);
}
使用未注册的类型解析,您可以即时进行注册。如何做到这一点在很大程度上取决于您使用的容器。例如,对于 Simple Injector,这看起来如下:
var container = new Container();
Assembly assembly = typeof(Thing).Assembly;
container.ResolveUnregisteredType += (s, e)
{
Type service = e.UnregisteredServiceType;
if (service.IsInterface)
{
var types = (
from type in asssembly.GetExportedTypes()
where service.IsAssignableFrom(type)
where !type.IsAbstract
where service.Name == "I" + type.Name
select type)
.ToArray();
if (types.Length == 1)
{
e.Register(Lifestyle.Transient.CreateRegistration(types[0], container));
}
}
};
这两种方法都可以避免您不断更新容器配置。