DependencyResolver 不解决依赖关系。为什么?
DependencyResolver doesn't Resolve dependencies. Why?
我在一个项目中使用 Unity 作为我的 IoC。
UnityConfig 是这样设置的...
public static class UnityConfig
{
private static readonly IUnityContainer container = new UnityContainer();
public static void ConfigureIoCContainer()
{
My.Composition.Builder.Compose(container);
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
}
/// <summary>
/// Gets the configured Unity container.
/// </summary>
public static IUnityContainer GetConfiguredContainer()
{
return container;
}
}
My.Composition.Builder.Compose() 这样做...
public static void Compose(IUnityContainer container)
{
var types = new List<Type>();
types.AddRange(Services.Interface.Builder.GetTypes(container));
types.AddRange(Services.Builder.GetTypes(container));
// ... lots more assemblies referenced here
var distinctTypes = types.Distinct();
container.RegisterTypes(distinctTypes, WithMappings.FromMatchingInterface, WithName.Default, WithLifetime.PerResolve);
}
现在,在上面引用的 2 个程序集中,我 return 3 种类型; IConfigUow
、ISecurityUow
和 IResourceUow
来自第一个,ConfigUow
、SecurityUow
和 ResourceUow
来自第二个。
如果我在 UnityConfig 中调用 My.Composition.Builder.Compose(container)
之后的行放置一个断点并查看已注册类型的列表,我可以看到我应该看到的所有内容...
{Microsoft.Practices.Unity.ContainerRegistration}
LifetimeManager: {Microsoft.Practices.Unity.PerResolveLifetimeManager}
LifetimeManagerType: {Name = "PerResolveLifetimeManager" FullName = "Microsoft.Practices.Unity.PerResolveLifetimeManager"}
MappedToType: {Name = "ConfigUow" FullName = "My.Services.Security.ConfigUow"}
Name: null
RegisteredType: {Name = "IConfigUow" FullName = "My.Services.Interface.Security.IConfigUow"}
{Microsoft.Practices.Unity.ContainerRegistration}
LifetimeManager: {Microsoft.Practices.Unity.PerResolveLifetimeManager}
LifetimeManagerType: {Name = "PerResolveLifetimeManager" FullName = "Microsoft.Practices.Unity.PerResolveLifetimeManager"}
MappedToType: {Name = "SecurityUow" FullName = "My.Services.Security.SecurityUow"}
Name: null
RegisteredType: {Name = "ISecurityUow" FullName = "My.Services.Interface.Security.ISecurityUow"}
{Microsoft.Practices.Unity.ContainerRegistration}
LifetimeManager: {Microsoft.Practices.Unity.PerResolveLifetimeManager}
LifetimeManagerType: {Name = "PerResolveLifetimeManager" FullName = "Microsoft.Practices.Unity.PerResolveLifetimeManager"}
MappedToType: {Name = "ResourceUow" FullName = "My.Services.Localization.ResourceUow"}
Name: null
RegisteredType: {Name = "IResourceUow" FullName = "My.Services.Interface.Localization.IResourceUow"}
但是,如果我让下一行执行以设置 DependencyResolver 并调用
DependencyResolver.Current.GetService<IConfigUow>();
null
的值是 returned。调用
DependencyResolver.Current.GetService<ISecurityUow>();
有效并且 return 是 SecurityUow
的实例。尝试解析 IResourceUow
也失败了。
我这辈子都看不出自己做错了什么。有人有什么想法吗?
更新
好的,所以通过调用 container.Resolve(IConfigUow)
我得到了一个被 DependencyResolver 屏蔽的异常。
错误表明我缺少类型映射。 ConfigUow
的构造函数如下所示...
public ConfigUow(ICrudRepo<AM.Configuration> crudRepo = null) : base(crudRepo)
{
CrudRepo = crudRepo ?? DependencyResolver.Current.GetService<IConfigRepo>();
Ctx = CrudRepo.GetContext();
}
我不知道我需要为使用泛型的类型显式调用 RegisterType()
。
所以,我需要做的就是像这样注册合适的类型...
container.RegisterType(typeof (ICrudRepo<>), typeof (CrudRepo<>));
一切都成功了。
对于未来的读者,这些页面证明是有帮助的...
- Registering Generic Parameters and Types (MSDN)
- Using Unity, how do you register type mappings for generics? (Whosebug)
答案是 DependencyResolver 掩盖了 IoC 容器抛出异常的事实。
发现解决问题并不难。邀请读者查看原始问题的 UPDATE 以了解我必须修复的内容以及我是如何修复的。
我在一个项目中使用 Unity 作为我的 IoC。
UnityConfig 是这样设置的...
public static class UnityConfig
{
private static readonly IUnityContainer container = new UnityContainer();
public static void ConfigureIoCContainer()
{
My.Composition.Builder.Compose(container);
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
}
/// <summary>
/// Gets the configured Unity container.
/// </summary>
public static IUnityContainer GetConfiguredContainer()
{
return container;
}
}
My.Composition.Builder.Compose() 这样做...
public static void Compose(IUnityContainer container)
{
var types = new List<Type>();
types.AddRange(Services.Interface.Builder.GetTypes(container));
types.AddRange(Services.Builder.GetTypes(container));
// ... lots more assemblies referenced here
var distinctTypes = types.Distinct();
container.RegisterTypes(distinctTypes, WithMappings.FromMatchingInterface, WithName.Default, WithLifetime.PerResolve);
}
现在,在上面引用的 2 个程序集中,我 return 3 种类型; IConfigUow
、ISecurityUow
和 IResourceUow
来自第一个,ConfigUow
、SecurityUow
和 ResourceUow
来自第二个。
如果我在 UnityConfig 中调用 My.Composition.Builder.Compose(container)
之后的行放置一个断点并查看已注册类型的列表,我可以看到我应该看到的所有内容...
{Microsoft.Practices.Unity.ContainerRegistration}
LifetimeManager: {Microsoft.Practices.Unity.PerResolveLifetimeManager}
LifetimeManagerType: {Name = "PerResolveLifetimeManager" FullName = "Microsoft.Practices.Unity.PerResolveLifetimeManager"}
MappedToType: {Name = "ConfigUow" FullName = "My.Services.Security.ConfigUow"}
Name: null
RegisteredType: {Name = "IConfigUow" FullName = "My.Services.Interface.Security.IConfigUow"}
{Microsoft.Practices.Unity.ContainerRegistration}
LifetimeManager: {Microsoft.Practices.Unity.PerResolveLifetimeManager}
LifetimeManagerType: {Name = "PerResolveLifetimeManager" FullName = "Microsoft.Practices.Unity.PerResolveLifetimeManager"}
MappedToType: {Name = "SecurityUow" FullName = "My.Services.Security.SecurityUow"}
Name: null
RegisteredType: {Name = "ISecurityUow" FullName = "My.Services.Interface.Security.ISecurityUow"}
{Microsoft.Practices.Unity.ContainerRegistration}
LifetimeManager: {Microsoft.Practices.Unity.PerResolveLifetimeManager}
LifetimeManagerType: {Name = "PerResolveLifetimeManager" FullName = "Microsoft.Practices.Unity.PerResolveLifetimeManager"}
MappedToType: {Name = "ResourceUow" FullName = "My.Services.Localization.ResourceUow"}
Name: null
RegisteredType: {Name = "IResourceUow" FullName = "My.Services.Interface.Localization.IResourceUow"}
但是,如果我让下一行执行以设置 DependencyResolver 并调用
DependencyResolver.Current.GetService<IConfigUow>();
null
的值是 returned。调用
DependencyResolver.Current.GetService<ISecurityUow>();
有效并且 return 是 SecurityUow
的实例。尝试解析 IResourceUow
也失败了。
我这辈子都看不出自己做错了什么。有人有什么想法吗?
更新
好的,所以通过调用 container.Resolve(IConfigUow)
我得到了一个被 DependencyResolver 屏蔽的异常。
错误表明我缺少类型映射。 ConfigUow
的构造函数如下所示...
public ConfigUow(ICrudRepo<AM.Configuration> crudRepo = null) : base(crudRepo)
{
CrudRepo = crudRepo ?? DependencyResolver.Current.GetService<IConfigRepo>();
Ctx = CrudRepo.GetContext();
}
我不知道我需要为使用泛型的类型显式调用 RegisterType()
。
所以,我需要做的就是像这样注册合适的类型...
container.RegisterType(typeof (ICrudRepo<>), typeof (CrudRepo<>));
一切都成功了。
对于未来的读者,这些页面证明是有帮助的...
- Registering Generic Parameters and Types (MSDN)
- Using Unity, how do you register type mappings for generics? (Whosebug)
答案是 DependencyResolver 掩盖了 IoC 容器抛出异常的事实。
发现解决问题并不难。邀请读者查看原始问题的 UPDATE 以了解我必须修复的内容以及我是如何修复的。