2016-10-24 23 views
0

我在Ninject wiki上阅读了一堆问题和所有文档,但我仍然怀疑并向自己提出问题,比如“我做对了吗?正确的方式来使用依赖注入时,只有在运行时才会知道一些参数

  1. 如果我需要使用控制器来初始化对象,该怎么办? 字段参数只会在运行时间

A)所以我需要的东西是这样的:

public class MyClass : IMyInterface 
    { 
     private string _field; 
     readonly IRepository _repo; 
     public MyClass(string field, IRepository repo) 
     { 
      _field = field; 
      _repo = repo; 
     } 
    } 

但如何正确地绑定呢?或者我应该永远忘记使用构造函数出于任何原因,但构造函数依赖注入?

B)并做到这一点,如:

public class MyClass : IMyInterface 
{ 
    private string _field; 
    readonly IRepository _repo; 
    public MyClass(IRepository repo) 
    { 
     _repo = repo; 
    } 
    public void Initialize(string field) 
    { 
     _field = field; 
    } 
} 

我认为这是不正常随时随地打电话的时候,我需要这个对象初始化函数或我错了?

据,如果你需要一个短暂的对象

相关性与构造器注入注入这个答案Can't combine Factory/DIDependency Inject (DI) "friendly" libraryIs there a pattern for initializing objects created via a DI container

使用抽象工厂往往是长期的,但有时你需要一个短暂的对象,或基于仅在运行时已知的值构建依赖项。

C)我应该做的,如:

public interface IMyInterface { } 
    public interface IMyFactory 
    { 
     MyClass Create(string field); 
    } 
    public class MyFactory : IMyFactory 
    { 
     private readonly IRepository _repo; 
     public MyFactory (IRepository repo) 
     { 
      _repo = repo; 
     } 
     public MyClass Create(string field) 
     { 
      return new MyClass(_repo, field); 
     } 
    } 
    public class MyClass : IMyInterface 
    { 
     private string _field; 
     readonly IRepository _repo; 
     public MyClass(IRepository repo, string field) 
     { 
      _repo = repo; 
      _field = field; 
     } 
    } 

如果我需要MyClass的另一个类我要去使用它像

public class OtherClass 
{ 
    private IMyInterface _myClass; 
    public OtherClass(IMyFactory factory) 
    { 
     _myClass = factory.Create("Something"); 
    } 
} 

是不是太笨重?

而我的问题是:我必须使用A,B或C情况?为什么?或者也许别的东西?

+0

请[编辑]并将您的问题分为多个聚焦的问题,因为它目前太宽泛了,它可能会以当前的形式关闭,尽管这是一个好的... – kayess

+0

@kayess完成。我截掉了一半的问题。感谢您的咨询 – PilgrimViis

+0

@PilgrimViis仍然不适合SO,不幸的是,可能是阅读常见问题的想法,也许可以在其他网站上发布这些内容。 – ChrisBint

回答

2

如果我需要使用控制器来初始化对象,该怎么办?只有在运行时才会知道字段参数?

如解释here,您的应用程序组件在初始化期间不应该要求运行时数据。相反,你应该可以:

  1. 通过API的方法调用或
  2. 通运行时数据检索特定抽象允许解决运行数据运行数据。

流行的看法相反,抽象工厂都几乎没有对这个问题的解决方案,这是因为:

而是为消费者降低复杂性,工厂反而会增加,因为而不是只具有复杂性,依赖于服务抽象IService,消费者现在需要依赖于IService和Abstract Factory IServiceFactory。当单元测试这样的类时,可以立即感觉到复杂度的增加。这不仅迫使我们测试消费者与服务的交互,还必须测试与工厂的交互。

如需详细讨论,请阅读this article

1

答案与往常一样,取决于。没有上下文,很难提供建议。

但是,有一件事我会毫不犹豫地做 - 配置注入“纯”字符串到组件。字符串可能意味着成千上万的事情,并且稍后可能很难支持该设计。当然,你可以定义一个注入到XController的字符串是一个到SQL的连接字符串,当注入到YController时将是一个授权令牌,但我怀疑它是可读的并且易于维护。

这虽这么说,我会选择选项ç或以下方法:

public class DescriptiveMeaningOfAClass 
    { 
     public string Value { get; set; } 
    } 

    public class MyClass : IMyInterface 
    { 
     private string _field; 
     readonly IRepository _repo; 
     public MyClass(DescriptiveMeaningOfAClass something, IRepository repo) 
     { 
      _field = something.Value; 
      _repo = repo; 
     } 
    } 
0

Personnaly我会用ChildKernel而不是直接引用构造混合A)和C)。 https://github.com/ninject/Ninject.Extensions.ChildKernel

在你的工厂:

var parentKernel = new StandardKernel(); 

var childKernel1 = new ChildKernel(parentKernel); 
childKernel1.Bind<string>().ToConstant("MyRuntimeValue"); 
var myClass = childKernel1.Get<MyClass>(); 

我没有测试它,但它应该工作。

相关问题