Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/260.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WPF应用程序中的Ninject:请求类型的实例_C#_Wpf_Dependency Injection_Ninject - Fatal编程技术网

C# WPF应用程序中的Ninject:请求类型的实例

C# WPF应用程序中的Ninject:请求类型的实例,c#,wpf,dependency-injection,ninject,C#,Wpf,Dependency Injection,Ninject,我正在开发一个WPF应用程序,它有很大一部分业务逻辑和数据处理。 根据使用IoC的想法,我决定使用Ninject作为这部分逻辑和数据处理的依赖注入程序 我已经初始化了ninject的内核,并将接口与App.xaml.cs文件中的具体类绑定在一起(即在默认的App类中)。到目前为止一切都很好 问题是,在我的应用程序中的某个地方,我需要一个类的两个具体实例(我不想在构造函数中作为参数传递)。 实际上我需要做的是: var instance1 = kernel.Get<IClassName>

我正在开发一个WPF应用程序,它有很大一部分业务逻辑和数据处理。 根据使用IoC的想法,我决定使用Ninject作为这部分逻辑和数据处理的依赖注入程序

我已经初始化了ninject的内核,并将接口与
App.xaml.cs
文件中的具体类绑定在一起(即在默认的App类中)。到目前为止一切都很好

问题是,在我的应用程序中的某个地方,我需要一个类的两个具体实例(我不想在构造函数中作为参数传递)。 实际上我需要做的是:

var instance1 = kernel.Get<IClassName>();
有类似的东西我可以用吗? 或者我是被迫使用服务定位器模式解决问题(我知道存在相互冲突的意见)?

如何使用该模式来实例化所述依赖关系? 您可以插入一个
Func
,当您稍后调用它时,它将返回一个新实例化的
T
。如果您只是想在“第一次使用”时延迟实例化单个实例,那么还有一个
Lazy

然后,您还可以定义接口工厂,如:

public interface IFooFactory
{
    IFoo Create();
}
使用相应的绑定:

Bind<IFooFactory>().ToFactory();
Bind<IFoo>().To<Foo>(); // add Singleton, or ToMethod binding,.. or whatever you require
Bind().ToFactory();
绑定()。到();//添加Singleton或ToMethod绑定,。。或者你需要的任何东西

因为您希望每个类使用多个依赖项,所以应该使用设计模式而不是DI容器来解决问题

至少有两种选择。以下是设置场景的一些基本框架:

public interface IPresenter
{
    void Present();
}

public interface IConsumer
{
    void DoSomething();
}

public class SomeConsumer : IConsumer
{
    private readonly IPresenter presenter;

    public SomeConsumer(IPresenter presenter)
    {
        if (presenter == null)
            throw new ArgumentNullException("presenter");
        this.presenter = presenter;
    }

    public void DoSomething()
    {
        this.presenter.Present();
    }
}
您可以使用,然后可以在列表中对演示者进行排序

public class Presenter1 : IPresenter
{
    public void Present()
    {
        // Do something here
    }
}

public class Presenter2 : IPresenter
{
    public void Present()
    {
        // Do something here
    }
}

public class Presenter3 : IPresenter
{
    public void Present()
    {
        // Do something here
    }
}

public class CompositePresenter : IPresenter
{
    private readonly IPresenter[] presenters;

    public CompositePresenter(IPresenter[] presenters)
    {
        if (presenters == null)
            throw new ArgumentNullException("presenters");
        this.presenters = presenters;
    }

    public void Present()
    {
        // Do nothing except delegate the call to the nested
        // instances. You may need to do some extra work to deal
        // with multiple return values, like add up the values
        // or decide which value works best for the scenario.
        foreach (var presenter in this.presenters)
        {
            presenter.Present();
        }
    }
}
然后将其连接起来,如:

var presenter1 = new Presenter1();
var presenter2 = new Presenter2();
var presenter3 = new Presenter3();
var compositePresenter = new CompositePresenter(new IPresenter[] {
    presenter1,
    presenter2,
    presenter3
});

var consumer = new SomeConsumer(compositePresenter);
var nullPresenter = new NullPresenter();
var presenter3 = new Presenter3(nullPresenter);
var presenter2 = new Presenter2(presenter3);
var presenter1 = new Presenter1(presenter2);

var consumer = new SomeConsumer(presenter1);
在Ninject中,上述内容如下所示:

var kernel = new StandardKernel();
kernel.Bind<Presenter1>().ToSelf();
kernel.Bind<Presenter2>().ToSelf();
kernel.Bind<Presenter3>().ToSelf();
kernel.Bind<IPresenter>().To<CompositePresenter>()
    .WithConstructorArgument("presenters", 
        new IPresenter[] { 
            kernel.Get<Presenter1>(), 
            kernel.Get<Presenter2>(),
            kernel.Get<Presenter3>() 
        });

// When SomeConsumer is injected into a constructor, its IPresenter 
// dependency will be wired as shown with the new keyword example above.
var kernel = new StandardKernel();
kernel.Bind<IPresenter>().To<NullPrenter>().WhenInjectedInto<Presenter3>();
kernel.Bind<IPresenter>().To<Presenter3>().WhenInjectedInto<Presenter2>();
kernel.Bind<IPresenter>().To<Presenter2>().WhenInjectedInto<Presenter1>();
kernel.Bind<IPresenter>().To<Presenter1>();

// When SomeConsumer is injected into a constructor, its IPresenter 
// dependency will be wired as shown with the new keyword example above.
然后将其连接起来,如:

var presenter1 = new Presenter1();
var presenter2 = new Presenter2();
var presenter3 = new Presenter3();
var compositePresenter = new CompositePresenter(new IPresenter[] {
    presenter1,
    presenter2,
    presenter3
});

var consumer = new SomeConsumer(compositePresenter);
var nullPresenter = new NullPresenter();
var presenter3 = new Presenter3(nullPresenter);
var presenter2 = new Presenter2(presenter3);
var presenter1 = new Presenter1(presenter2);

var consumer = new SomeConsumer(presenter1);
在Ninject中,上述内容如下所示:

var kernel = new StandardKernel();
kernel.Bind<Presenter1>().ToSelf();
kernel.Bind<Presenter2>().ToSelf();
kernel.Bind<Presenter3>().ToSelf();
kernel.Bind<IPresenter>().To<CompositePresenter>()
    .WithConstructorArgument("presenters", 
        new IPresenter[] { 
            kernel.Get<Presenter1>(), 
            kernel.Get<Presenter2>(),
            kernel.Get<Presenter3>() 
        });

// When SomeConsumer is injected into a constructor, its IPresenter 
// dependency will be wired as shown with the new keyword example above.
var kernel = new StandardKernel();
kernel.Bind<IPresenter>().To<NullPrenter>().WhenInjectedInto<Presenter3>();
kernel.Bind<IPresenter>().To<Presenter3>().WhenInjectedInto<Presenter2>();
kernel.Bind<IPresenter>().To<Presenter2>().WhenInjectedInto<Presenter1>();
kernel.Bind<IPresenter>().To<Presenter1>();

// When SomeConsumer is injected into a constructor, its IPresenter 
// dependency will be wired as shown with the new keyword example above.
var-kernel=new-StandardKernel();
kernel.Bind().To().WhenInjectedInto();
kernel.Bind().To().WhenInjectedInto();
kernel.Bind().To().WhenInjectedInto();
kernel.Bind().To();
//当某个使用者被注入构造函数时,其IPresenter
//依赖关系将如上面的新关键字示例所示进行连接。

使用设计模式的优点是,最终得到的是完全模块化、可扩展的松散耦合代码,甚至独立于DI容器。

您可以通过服务使内核可用,该服务将为需要直接使用项目DI的类提供帮助。@MotiAzu您的建议和服务定位器机制有什么区别?您可以将IKernel作为构造函数参数注入。然后用它来构造你需要的对象。和服务定位器没有太大区别,但在我看来似乎更好。不需要静态方法。上面的两个示例都是服务定位器的示例。您可能可以使用模式来解决您的用例,但实际上您还没有解释您打算用实例做什么。它们都将被您的服务使用,还是您希望为正确的服务选择正确的一个?@NightOwl888它们都将被服务使用。从未听说过该扩展。我会检查的。