我似乎找不到一种方法来注册程序集中的所有类型或相关类型(基于基类或接口(interface))以进行 Web API 集成。例如我有以下内容:
public interface IBaseService { }
public interface IServiceA : IBaseService { }
public interface IServiceB : IBaseService { }
public interface IServiceX { }
public class ServiceA : IServiceA {}
public class ServiceB : IServiceB {}
public class ServiceX : IServiceX {}
// register the types
container.RegisterWebApiRequest<IServiceA, ServiceA >();
// I have to repeat this for all types I have
container.RegisterWebApiRequest<IServiceB, ServiceB >();
//
container.RegisterWebApiRequest<IServiceX, ServiceX >();
是否有可用于 Web API 请求的等效 RegisterAll
?如果不直接支持,有没有办法破解它并实现我需要的?
最佳答案
我不确定 Simple Injector 是否直接支持它,但使用 .NET 反射相当容易。
支持代码
请注意此代码是通用的 - 它适用于任何 DI 容器,而不仅仅是 Simple Injector。
internal class CommonConventions
{
public static void RegisterDefaultConventions(
Action<Type, Type> registerMethod,
Assembly[] interfaceAssemblies,
Assembly[] implementationAssemblies,
Type[] excludeTypes,
string excludeRegEx)
{
List<Type> interfaces = new List<Type>();
foreach (var assembly in interfaceAssemblies)
interfaces.AddRange(GetInterfaces(assembly));
foreach (var interfaceType in interfaces)
{
if (!IsExcludedType(interfaceType, excludeTypes, excludeRegEx))
{
List<Type> implementations = new List<Type>();
foreach (var assembly in implementationAssemblies)
implementations.AddRange(GetImplementationsOfInterface(assembly, interfaceType).Where(implementation => !IsExcludedType(implementation, excludeTypes, excludeRegEx)).ToArray());
// Use the default name ITypeName = TypeName
Type implementationType = implementations.Where(implementation => IsDefaultType(interfaceType, implementation)).FirstOrDefault();
if (implementationType != null)
{
System.Diagnostics.Debug.WriteLine("Auto registration of {1} : {0}", interfaceType.Name, implementationType.Name);
registerMethod(interfaceType, implementationType);
}
}
}
}
private static bool IsExcludedType(Type type, Type[] excludeTypes, string excludeRegEx)
{
return IsExcludedType(type, excludeTypes) || IsExcludedType(type, excludeRegEx);
}
private static bool IsExcludedType(Type type, Type[] excludeTypes)
{
return excludeTypes.Contains(type);
}
private static bool IsExcludedType(Type type, string excludeRegEx)
{
if (string.IsNullOrEmpty(excludeRegEx)) return false;
return Regex.Match(type.Name, excludeRegEx, RegexOptions.Compiled).Success;
}
private static bool IsDefaultType(Type interfaceType, Type implementationType)
{
return interfaceType.Name.Equals("I" + implementationType.Name);
}
private static IEnumerable<Type> GetInterfaces(Assembly assembly)
{
return assembly.GetTypes().Where(t => t.IsInterface);
}
private static IEnumerable<Type> GetImplementationsOfInterface(Assembly assembly, Type interfaceType)
{
return assembly.GetTypes().Where(t =>
!t.IsInterface &&
!t.IsAbstract &&
interfaceType.IsAssignableFrom(t) &&
t.GetConstructors(BindingFlags.Public | BindingFlags.Instance)
.Any(type => type.GetParameters().Select(p => p.ParameterType).All(p => (p.IsInterface || p.IsClass) && p != typeof(string))));
}
}
用法
var currentAssembly = typeof(SomeLocalType).Assembly;
var interfaceAssemblies = new Assembly[] {
currentAssembly
/*, Additional Assemblies */
};
var implementationAssemblies = new Assembly[] {
currentAssembly
/*, Additional Assemblies */
};
var excludeTypes = new Type[]
{
// Use this array to add types you wish to explicitly exclude from convention-based
// auto-registration. By default all types that either match I[TypeName] = [TypeName]
// will be automatically wired up.
//
// If you want to override a type that follows the convention, you should add the name
// of either the implementation name or the interface that it inherits to this list and
// add your manual registration code below. This will prevent duplicate registrations
// of the types from occurring.
// Example:
// typeof(SiteMap),
// typeof(SiteMapNodeVisibilityProviderStrategy)
};
var scopedLifestyle = new WebApiRequestLifestyle();
CommonConventions.RegisterDefaultConventions(
// This registers with a SimpleInjector container
(interfaceType, implementationType) =>
container.Register(interfaceType, implementationType, scopedLifestyle),
interfaceAssemblies,
implementationAssemblies,
excludeTypes,
string.Empty);
关于c# - 用于 Web Api 的 SimpleInjector RegisterAll,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31979192/