标签: unity-container

Prism,将Views和ViewModels与Unity连接,试图理解它

使用Unity创建视图和视图模型

使用Unity作为依赖注入容器与使用MEF类似,并且支持基于属性和基于构造函数的注入.主要区别在于通常不会在运行时隐式发现类型; 相反,他们必须在容器中注册.

通常,您在视图模型上定义接口,以便视图模型的特定具体类型可以与视图分离.例如,视图可以通过构造函数参数定义其对视图模型的依赖性,如此处所示.C#

public QuestionnaireView() 
{
    InitializeComponent(); 
}

public QuestionnaireView(QuestionnaireViewModel viewModel) : this() 
{
    this.DataContext = viewModel;
}
Run Code Online (Sandbox Code Playgroud)

默认的无参数构造函数是允许视图在设计时工具(如Visual Studio和Expression Blend)中工作所必需的.

或者,您可以在视图上定义只写视图模型属性,如此处所示.Unity将实例化所需的视图模型,并在实例化视图后调用属性setter.C#

public QuestionnaireView() 
{
    InitializeComponent(); 
}

[Dependency] 
public QuestionnaireViewModel ViewModel 
{
    set { this.DataContext = value; } 
}
Run Code Online (Sandbox Code Playgroud)

视图模型类型已在Unity容器中注册,如此处所示.C#

IUnityContainer container;
container.RegisterType<QuestionnaireViewModel>();
Run Code Online (Sandbox Code Playgroud)

然后可以通过容器实例化视图,如此处所示.C#

IUnityContainer container;
var view = container.Resolve<QuestionnaireView>();
Run Code Online (Sandbox Code Playgroud)
  1. 如果我省略了有关注册ViewModel和实例化View的代码的最后部分,并且只使用将ViewModel挂钩到View的两种方法中的任何一种(使用构造函数或使用属性),那么看起来是ViewModel和View似乎一切都运转良好.那么注册ViewModel并实例化View的代码需要什么?

  2. 第一个例子,使用构造函数挂钩View和ViewModel,没有提到所有的Unity,所以Unity实际上在这里使用了吗?

  3. 使用基于属性的注射比使用基于construtor的注射有任何优势还是它们完全相同?

  4. 文本的第一部分说"*通常,您在视图模型上定义一个接口,以便视图模型的特定具体类型可以与视图分离",然后给出一个示例.然而,这个例子根本没有提到接口.这里发生了什么,我错过了什么吗?

c# wpf prism unity-container mvvm

11
推荐指数
1
解决办法
1万
查看次数

Unity注册一个接口多个对象并告诉Unity在哪里注入它们

嗨,我一直在努力告诉Unity,如果它有多个实现,我希望它将它们注入不同的类中.这就是我的意思:

比方说,我有一个接口IProductCatalogService和两个实现 ProductCatalog : IProductCatalogServiceProductCatalogService : 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 …

c# unity-container

11
推荐指数
1
解决办法
2万
查看次数

ASP.NET MVC和Unity 1.2容器问题

我正在尝试使用Unity容器来更轻松地对我的控制器进行单元测试.我的控制器使用一个接受Repository接口的构造函数.在global.asax文件中,我实例化一个UnityContainerFactory并将其注册到MVC框架,然后注册存储库及其实现.我将[Dependency]属性添加到控制器的CTOR Repository参数中.这一切似乎都可以正常工作,除了有时工厂的GetControllerInstance(Type controllerType)被多次调用并传递一个null参数作为controllerType.

对工厂的第一次调用是正确的,并且controllerType"ProductsController"作为参数传入.但有时候,在视图显示为控制器的空值后,工厂被调用了几次,我不知道为什么.当传递控制器类型的正确值时,"Call Stack"对我有意义,但是当传递null时,我不确定为什么或谁在进行调用.有任何想法吗?

该示例的代码和调用堆栈如下所示.

有效时调用堆栈

Test.DLL!Test.UnityHelpers.UnityControllerFactory.GetControllerInstance(System.Type controllerType = {Name ="ProductsController"FullName ="Test.Controllers.ProductsController"})第23行C#Test.DLL!Test._Default.Page_Load(object sender = {ASP.default_aspx},System.EventArgs e = {System.EventArgs})第18行+ 0x1a字节C#

在controllerType传递NULL时调用Stack

Test.DLL!Test.UnityHelpers.UnityControllerFactory.GetControllerInstance(System.Type controllerType = null)第27行C#

首先,我创建了一个UnityControllerFactory

public class UnityControllerFactory : DefaultControllerFactory
{
    UnityContainer container;

    public UnityControllerFactory(UnityContainer container)
    {
        this.container = container;
    }

    protected override IController GetControllerInstance(Type controllerType)
    {
        if (controllerType != null)
        {
            return container.Resolve(controllerType) as IController;
        }
        else
        {
            return null; // I never expect to get here, but I do sometimes, the callstack does not show the caller …
Run Code Online (Sandbox Code Playgroud)

asp.net-mvc unity-container

10
推荐指数
1
解决办法
2287
查看次数

我可以像在Autofac中那样在Unity中的模块中注册我的类型吗?

我非常熟悉Autofac,我非常喜欢Autofac的一个功能是注册模块.有谁知道我怎么能用Unity做到这一点?如果有的话,我很难找到在Google中使用哪些术语来提出相等的统一值.


public class Global : HttpApplication, IContainerProviderAccessor
{
   private static IContainerProvider _containerProvider;

   protected void Application_Start(object sender, EventArgs e)
   {
      var builder = new ContainerBuilder();
      builder.RegisterModule(new MyWebModule());

      _containerProvider = new ContainerProvider(builder.Build());
   }

[...]

   public IContainerProvider ContainerProvider
   {
      get { return _containerProvider; }
   }
}

public class MyWebModule: Module
{
    protected override void Load(ContainerBuilder builder)
    {
       builder.RegisterModule(new ApplicationModule());
       builder.RegisterModule(new DomainModule());
    }
}

public class ApplicationModule: Module
{
    protected override void Load(ContainerBuilder builder)
    {
       builder.Register(c => new ProductPresenter(c.Resolve<IProductView>()))
                .As<ProductPresenter>()
                .ContainerScoped();
    }
}

.net c# ioc-container inversion-of-control unity-container

10
推荐指数
2
解决办法
5530
查看次数

实体框架返回旧数据

我有一个问题,EF没有返回3层WPF应用程序中的最新数据,我怀疑它与我如何处理我的上下文的生命周期有关.这是场景:

UnitOfWork中包含几个存储库.还有一个服务(MyService),它使用UnitOfWork.还必须直接从UI调用此UnitOfWork,而不通过服务.

在我的主窗口的ViewModel中,我创建了一个新窗口(首先使用ViewModel):

var dialog = new DialogViewModel(_eventAggregator, _unitOfWork, Container.Resolve<CarService>());
Run Code Online (Sandbox Code Playgroud)

这个主窗口ViewModel有一个UnitOfWork,它已经在构造函数中注入,并传递给DialogViewModel.

CarService的构造函数也需要一个UnitOfWork,它也在它的构造函数中注入:

public CarService(IUnitOfWork unitOfWork){
    _unitOfWork = unitOfWork;
}
Run Code Online (Sandbox Code Playgroud)

当在DialogViewModel中使用CarService进行查询以检索某些数据并进行一些更新时,它第一次正常工作.但是,当下次检索该数据时进行相同的查询,而不是返回最新的修改后的数据,它将返回旧的/缓存的数据.使用UnitOfWork(在CarService内部)的查询如下所示:

var values = _unitOfWork.GarageRepository.GetSomeValues();
_unitOfWork.GarageRepository.MakeSomeChangesToTheValuesUsingStoredProcedure();
Run Code Online (Sandbox Code Playgroud)

第二次调用它时,值不包含最新版本的数据; 但它已在DB中成功更新.

我正在使用Unity进行DI,这就是我的容器的样子:

public class Container
{
     public static UnityContainer Container = new UnityContainer();

     // Called once in the AppBoostraper, as soon as the GUI application starts 
     public void BuildUp()
     {
          Container.RegisterType<IUnitOfWork, UnitOfWork>();
          Container.RegisterType<ICarService, CarService>();
     }
}
Run Code Online (Sandbox Code Playgroud)

为什么不返回正确的数据,我该如何解决?

c# entity-framework dependency-injection unity-container unit-of-work

10
推荐指数
1
解决办法
1万
查看次数

带有参数条件的简单工厂,使用Unity 2.0

假设我有一个Simple Factory(SimpleProductFactory),它使用条件参数来确定如何创建Product如下:

public static class SimpleProductFactory
{
    public static Product MakeProduct(Condition condition)
    {
        Product product;
        switch(condition)
        {
            case Condition.caseA:
                product = new ProductA();
                // Other product setup code
                break;
            case Condition.caseA2:
                product = new ProductA();
                // Yet other product setup code
                break;
            case Condition.caseB:
                product = new ProductB();
                // Other product setup code
                break;
        }
        return product;
    }
}
Run Code Online (Sandbox Code Playgroud)

某个客户端使用此工厂来处理包含以下条件的运行时数据:

public class SomeClient
{
    // ...
    public void HandleRuntimeData(RuntimeData runtimeData)
    {
        Product product …
Run Code Online (Sandbox Code Playgroud)

.net c# factory dependency-injection unity-container

10
推荐指数
2
解决办法
9517
查看次数

在Unity.MVC4或Unity(3.0)中找不到PerRequestLifetimeManager类

我想找到PerRequestLifetimeManager.在MSDN中,它表示它是Unity 3程序集的一部分.

我通过Nuget安装了Unity.Mvc4.package.config说我正在使用Unity 3.0:

在此输入图像描述

Microsoft.Practices.Unity.dll说我使用Unity 3.0

在此输入图像描述

我使用对象浏览器查看了DLL内部,并且没有找到PerRequestLifetimeManager.

我在这里错过了什么吗?

如果有人会建议另一个类,我打算使用这里找到的自定义PerRequestLifetimeManager (如果我找不到该类).

编辑:

我已经卸载了Unity.Mvc4并直接在包控制台中安装了Unity3.0,这是我得到的:

PM> Install-Package Unity -version 3.0.1304.1
'Unity 3.0.1304.1' already installed.
Successfully added 'Unity 3.0.1304.1' to RedLions.Presentation.Web.
Run Code Online (Sandbox Code Playgroud)

我仍然找不到PerRequestLifetimeManager类,即使在官方库中也是如此.

c# unity-container asp.net-mvc-4

10
推荐指数
1
解决办法
9401
查看次数

asp.net identity 2.0统一不解析默认用户存储

尝试使用Unity.Mvc5和使用Identity 2.0和Identity 2.0 Samples样板的MVC 5应用程序配置Unity时,我得到以下异常.我已经阅读了这个SO 配置Unity DI的ASP.NET身份,我仍然不清楚我错过了什么.我在这做错了什么?

当前类型System.Data.Common.DbConnection是一个抽象类,无法构造.你错过了类型映射吗?

[ResolutionFailedException:依赖项的解析失败,type ="myApp.Web.Controllers.AccountController",name ="(none)".在解决时发生异常:

异常是:InvalidOperationException - 当前类型System.Data.Common.DbConnection是一个抽象类,无法构造.你错过了类型映射吗?

在例外时,容器是:

解析myApp.Web.Controllers.AccountController,(无)解析构造函数myApp.Web.Controllers.AccountController(myApp.Web.Models.ApplicationUserManager userManager)的参数"userManager"解析myApp.Web.Models.ApplicationUserManager,(无)解析参数构造函数myApp.Web.Models.ApplicationUserManager的"store"(Microsoft.AspNet.Identity.IUserStore 1[[myApp.Web.DAL.Profiles.ApplicationUser, myApp.Web, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]] store) Resolving Microsoft.AspNet.Identity.EntityFramework.UserStore1 [myApp.Web.DAL.Profiles.ApplicationUser],(无)(从Microsoft.AspNet.Identity.IUserStore 1[myApp.Web.DAL.Profiles.ApplicationUser], (none)) Resolving parameter "context" of constructor Microsoft.AspNet.Identity.EntityFramework.UserStore1 [[myApp ]映射).Web.DAL.Profiles.ApplicationUser,myApp.Web,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null]](System.Data.Entity.DbContext context)Resolving System.Data.Entity.DbContext,(none)解析构造函数System.Data.Entity.DbContext的参数"existingConnection"(System.Data.Common.DbConnection existingConnection,System.Data.Entity.Infrastructure.DbCompiledModel model,System.Boolean contextOwnsConnection)Resolving System.Data.Common.DbConnection,(没有)

帐户控制器,因为我已修改它

 public AccountController(ApplicationUserManager userManager)
 {
      _userManager = userManager;
 }

 private ApplicationUserManager _userManager;
Run Code Online (Sandbox Code Playgroud)

我已注册的容器

container.RegisterType<ApplicationUserManager>(new HierarchicalLifetimeManager());
container.RegisterType<IUserStore<ApplicationUser>, UserStore<ApplicationUser>>(new HierarchicalLifetimeManager());
Run Code Online (Sandbox Code Playgroud)

asp.net-mvc dependency-injection unity-container asp.net-identity asp.net-identity-2

10
推荐指数
1
解决办法
1万
查看次数

如何设置Unity注册约定?

使用结构图,您可以注册一个约定,它不仅可以调整类型,还可以在对象创建期间进行干预.我怎么能用Unity做到这一点.

public class SettingsRegistration : IRegistrationConvention
{
    public void Process(Type type, Registry registry)
    {
        if (!type.IsAbstract && typeof(ISettings).IsAssignableFrom(type))
        {
            registry.For(type).Use(x =>
            {
                var svc = x.GetInstance<ISettingService>();
                return svc.LoadSetting(type);
            });
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

c# dependency-injection unity-container

10
推荐指数
1
解决办法
4373
查看次数

仅从指定的命名空间解析依赖关系

我可以使用此语句自动注册实现接口的所有类型

IUnityContainer container = new UnityContainer();

container.RegisterTypes(
    AllClasses.FromAssembliesInBasePath(),
    WithMappings.FromMatchingInterface,
    WithName.Default,
    WithLifetime.Transient);
ICustomer result = container.Resolve<ICustomer>();
Run Code Online (Sandbox Code Playgroud)

如何为接口和实现指定命名空间?

即:只有接口Framework.RepositoryInterfaces才能通过类型解析Framework.RepositoryImplementations.

c# conventions unity-container

10
推荐指数
1
解决办法
255
查看次数