2015-07-20 69 views
1

This answer显示了如何使用不带参数的工厂接口来解析实例。如何在具有参数的简单喷油器中实现工厂接口

我使用下面的代码

public interface ISimpleBarFactory 
{ 
    Bar CreateBar(int value); 
} 

public sealed class SimpleBarFactory : ISimpleBarFactory 
{ 
    private readonly Container _container; 
    public SimpleBarFactory (Container container) 
    { 
     _container = container; 
    } 

    public Bar CreateBar(int value) 
    { 
     _container.Register(() => new Bar(vlue)); 
     return _container.GetInstance<Bar>(); 
    } 
} 

解决具有构造函数的参数情况。

The container can't be changed after the first call to GetInstance, GetAllInstances and Verify.

这是解决使用工厂接口与参数情况下,正确的做法:

然而,使用工厂来实例化服务类,当我得到下面的异常?

更新

以下是我的代码。我正在从Ninject迁移代码。

public interface IFormsUIFactory 
{ 
    AccountUI CreateAccountUI(Account account); 
} 

public class FormsUIFactory 
{ 
    private readonly IFormsUIFactory _uiFactory; 
    public FormsUIFactory(IFormsUIFactory uiFactory) 
    { 
     _uiFactory = uiFactory; 
    } 

    public void CreateAccountUI(Account account) 
    { 
     _uiFactory.CreateAccountUI(account); 
    } 
} 

UI类将被注入

public partial class AccountUI : Form 
{ 
    private readonly IAccountMaintenanceProcessor _processor; 
    private readonly Account _account; 
    public AccountUI(IAccountMaintenanceProcessor accountProcessor, Account account) 
    {  
     _processor = accountProcessor; 
     _account = account; 
    } 

} 

实例化代码:

var account = new Account(); 
// Populate values for the account 

var frm = _uiFactory.CreateAccountUI(account); 
+1

您使用的是什么IoC? –

+0

关键是你应该在应用程序启动时只注册'Bar' ** **一次**。并使用像动态参数解析来传递'value'。您需要知道您使用的是哪种IoC,因为每个IoC都有不同的方式(语法) –

+0

我正在使用简单喷油器 – kagundajm

回答

1

您有由事实,你是混合运行时数据造成的问题(你Account)对象,与组件。您的DI容器负责构建组件的对象图。这些组件通常应该是无状态的,并且运行时数据应该使用方法调用流过对象图。将运行时数据注入到组件的构造函数中,使这些组件变得有状态并以多种不同方式使应用程序复杂化;你目睹了今天这些复杂情况之一。但是这样做有很多缺点。例如,将运行时数据注入构造函数使得无法验证您的对象图(使用自动化测试),并且使您的应用程序在运行时很容易中断。因此,这决不是Simple Injector特有的,但Simple在解决服务时不允许传递运行时值,从而使问题更加突出。 你可以找到关于这个here的详细解释。

因此,尽量让组件尽可能保持无状态,并至少将运行时数据保留在构造函数之外。实现此目的的一种简单方法是在表单中添加一个属性,以允许设置您正在使用的实体。通用接口可以被添加到一个表单,允许这样的:

interface IForm<TEntity> 
{ 
    TEntity Entity { get; set; } 
} 

此通用接口可以在IFormFactory抽象使用:

interface IFormFactory 
{ 
    TForm CreateFormFor<TForm, TEntity>(TEntity entity) 
     where TForm : Form, IForm<TEntity>; 
} 

创造IFormFactory的实现是那么容易,因为这样的:

public class FormFactory : IFormFactory 
{ 
    private readonly Container container; 

    public FormFactory(Container container) { 
     this.container = container; 
    } 

    public TForm CreateFormFor<TForm, TEntity>(TEntity entity) 
     where TForm : Form, IForm<TEntity> { 
     var form = this.container.GetInstance<TForm>(); 
     form.Entity = entity; 
     return form; 
    } 
} 
+0

感谢您的帮助和澄清。我从来没有意识到注入运行时数据有很多缺点。 – kagundajm

相关问题