我偶然发现了这个:
在Unity容器中,我想注册IDictionary<TK, TV>; 假设它是IDictionary<string, int>
_unityContainer = new UnityContainer()
.RegisterType<IDictionary<string, int>, Dictionary<string, int>>();
Run Code Online (Sandbox Code Playgroud)
但如果我试试
var d = _unityContainer.Resolve<IDictionary<string, int>>();
Run Code Online (Sandbox Code Playgroud)
它无法解决......
我明白了......
Microsoft.Practices.Unity.ResolutionFailedException:Microsoft.Practices.Unity.ResolutionFailedException:依赖项的解析失败,type ="System.Collections.Generic.IDictionary`2 [System.String,System.Int32]",name ="(none )".在解决时发生异常:
异常是:InvalidOperationException - 类型Dictionary`2有多个长度为2的构造函数.无法消除歧义.
在例外时,容器是:
解析System.Collections.Generic.Dictionary 2[System.String,System.Int32],(none) (mapped from System.Collections.Generic.IDictionary2 [System.String,System.Int32],(无))---> System.InvalidOperationException:类型Dictionary`2有多个长度为2的构造函数.无法消除歧义..
所以看起来它已经找到要解决的类型(正在Dictionary<string, int>)但未能将它新起来......
怎么团结不能解决这种类型?如果我输入
IDictionary<string, int> d = new Dictionary<string, int>()
Run Code Online (Sandbox Code Playgroud)
这样可行...
有任何想法吗?
谢谢!
使用Unity创建视图和视图模型
使用Unity作为依赖注入容器与使用MEF类似,并且支持基于属性和基于构造函数的注入.主要区别在于通常不会在运行时隐式发现类型; 相反,他们必须在容器中注册.
通常,您在视图模型上定义接口,以便视图模型的特定具体类型可以与视图分离.例如,视图可以通过构造函数参数定义其对视图模型的依赖性,如此处所示.C#
Run Code Online (Sandbox Code Playgroud)public QuestionnaireView() { InitializeComponent(); } public QuestionnaireView(QuestionnaireViewModel viewModel) : this() { this.DataContext = viewModel; }默认的无参数构造函数是允许视图在设计时工具(如Visual Studio和Expression Blend)中工作所必需的.
或者,您可以在视图上定义只写视图模型属性,如此处所示.Unity将实例化所需的视图模型,并在实例化视图后调用属性setter.C#
Run Code Online (Sandbox Code Playgroud)public QuestionnaireView() { InitializeComponent(); } [Dependency] public QuestionnaireViewModel ViewModel { set { this.DataContext = value; } }视图模型类型已在Unity容器中注册,如此处所示.C#
Run Code Online (Sandbox Code Playgroud)IUnityContainer container; container.RegisterType<QuestionnaireViewModel>();然后可以通过容器实例化视图,如此处所示.C#
Run Code Online (Sandbox Code Playgroud)IUnityContainer container; var view = container.Resolve<QuestionnaireView>();
如果我省略了有关注册ViewModel和实例化View的代码的最后部分,并且只使用将ViewModel挂钩到View的两种方法中的任何一种(使用构造函数或使用属性),那么看起来是ViewModel和View似乎一切都运转良好.那么注册ViewModel并实例化View的代码需要什么?
第一个例子,使用构造函数挂钩View和ViewModel,没有提到所有的Unity,所以Unity实际上在这里使用了吗?
使用基于属性的注射比使用基于construtor的注射有任何优势还是它们完全相同?
文本的第一部分说"*通常,您在视图模型上定义一个接口,以便视图模型的特定具体类型可以与视图分离",然后给出一个示例.然而,这个例子根本没有提到接口.这里发生了什么,我错过了什么吗?
我有这个代码:
1: IUnityContainer container = new UnityContainer();
2: container.LoadConfiguration();
Run Code Online (Sandbox Code Playgroud)
第1行有效,但第2行没有.找不到LoadConfiguration作为成员.我想,我已经注册了所有的团结.为什么找不到LoadConfiguration()?
可以将一种类型注册到多个接口吗?
我有类实现两个接口
MyService : IService1, IServier2 {}
Run Code Online (Sandbox Code Playgroud)
我想为这两个接口注册这种类型.
container.RegisterType<IService1, MyService>(CreateLifetime());
container.RegisterType<IService2, MyService>(CreateLifetime());
Run Code Online (Sandbox Code Playgroud)
不幸的是,在解决之后,我有两个不同的实例.我试过使用共同的生命,但后来我收到了消息,我不能.
我有一个类,其构造函数如下所示:
public BatchService(IRepository repository, ILogger logger, string user)
Run Code Online (Sandbox Code Playgroud)
在我的DI bootstrapper类中,我有以下RegisterType命令:
.RegisterType<BatchService>(
new InjectionConstructor(
new ResolvedParameter<IRepository>("SomeRepository"),
new ResolvedParameter<ILogger>("DatabaseLogger")))
Run Code Online (Sandbox Code Playgroud)
在我的客户端代码中,我想实例化BatchService如下:
BatchService batchService = DIContainer.Resolve<BatchService>()
Run Code Online (Sandbox Code Playgroud)
如您所见,我有一个字符串参数user作为构造函数的一部分被调用BatchService,它不是DI逻辑的一部分.如果我需要user在BatchService课堂上使用,我应该如何最好地处理这种情况?
我尝试运行以下代码:
using System.Web.Http;
using System.Web.Mvc;
using Conduit.Mam.ClientSerivces.Dal.Configuration;
using MamInfrastructure.Common.Dal;
using MamInfrastructure.Common.Logger;
using MamInfrastructure.Logger;
using Microsoft.Practices.Unity;
using Unity.WebApi;
namespace Conduit.Mam.ClientServices.Common.Initizliaer
{
public static class Initializer
{
private static bool isInitialize;
private static readonly object LockObj = new object();
private static IUnityContainer defaultContainer = new UnityContainer();
static Initializer()
{
Initialize();
}
public static void Initialize()
{
if (isInitialize)
return;
lock (LockObj)
{
IUnityContainer container = defaultContainer;
//registering Unity for web API
GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(container);
//registering Unity for MVC
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
container.RegisterType<IDal<ClientService.DAL.EntityFramework.MamConfiguration>, …Run Code Online (Sandbox Code Playgroud) 我按照下面链接的示例来设置统一以使用我的服务层.我的项目设置与本文中的项目非常相似,我理解除了为什么在注册服务依赖项时使用PerThreadLifetimeManager的所有内容.请记住,我也在使用我的服务层中使用的通用存储库和单元工作.大多数统一示例使用默认(瞬态)生命周期管理器,因为我的设置类似于下面的设置,我想知道为什么我应该使用PerThreadLifeimeManager?我正在为我当前的表示层使用ASP.NET Web表单项目,如果它发生了任何变化.
container.RegisterType<ICatalogService, CatalogService>(new PerThreadLifetimeManager())
Run Code Online (Sandbox Code Playgroud)
dependency-injection unity-container unit-of-work object-lifetime repository-pattern
嗨,我一直在努力告诉Unity,如果它有多个实现,我希望它将它们注入不同的类中.这就是我的意思:
比方说,我有一个接口IProductCatalogService和两个实现
ProductCatalog : IProductCatalogService和ProductCatalogService : IProductCatalogService.
我如何告诉Unity,对于类AI,我希望在我的构造函数中传递一个类型的实例,ProductCatalog而对于Class B我想要一个实例ProductCatalogService.
我在ASP.NET Web API项目中使用Unity,并在中设置了解析器GLobalConfiguration.
对于简单的1对1注册,一切正常.
这是我尝试过但它似乎不起作用:
public class DependencyServiceModel
{
public Type From { get; set; }
public Type To { get; set; }
public IEnumerable<Type> ForClasses { get; set; }
}
public void RegisterTypeForSpecificClasses(DependencyServiceModel dependencyService)
{
foreach (var forClass in dependencyService.ForClasses)
{
string uniquename = Guid.NewGuid().ToString();
Container.RegisterType(dependencyService.From,
dependencyService.To, uniquename);
Container.RegisterType(forClass, uniquename,
new InjectionConstructor(
new ResolvedParameter(dependencyService.To)));
}
}
Run Code Online (Sandbox Code Playgroud)
在DependencyServiceModel …
Unity容器将自动解析它可以自己解决的任何类型,而无需手动注册.这在某些方面很好,但我遇到的问题是它使用了TransientLifetimeManager这种类型的分辨率,而我几乎总是想要一个ContainerControlledLifetimeManager.当然,我仍然可以手动将我的类型注册为单身人士,但如果我忘了,而不是在启动时获得未处理的异常,应用程序将成功启动,一切似乎都有效.但是最终会出现一些错误,可能是非常微妙的,难以诊断的错误,因为有一个类型的多个实例意味着单身.
所以我的问题是:有没有办法可以指定不同的默认生命周期管理器或完全禁用默认的自动解析行为,并将容器限制为我自己注册的类型(直接或通过我自己的约定)?
ContainerControlledLifetimeManager和HierarchicalLifetimeManager之间的一般区别是什么?我知道ContainerControlledLifetimeManager表示单例,即DI容器将为每个需要依赖的类型创建一个新实例.我阅读了有关理解终身经理的有用文章.我将容器创建的实例的哈希码与不同的生命周期管理器进行了比较.如果我使用ContainerControlledLifetimeManager,每个请求都有相同的实例,但是当我使用HierarchicalLifetimeManager时,我得到了不同的哈希码.正如文章中所写,每个子容器都将创建自己的实例.我不完全理解它.父母和孩子是否会有相同的实例?如果我没有孩子会怎么样?什么时候应该使用这个终身经理?请你能解释一下吗?