问题描述
在我的应用程序中,我正在使用Ninject和NamedScopeExtension.对象图中较深的对象之一需要访问定义命名范围的根对象.在我看来,DefinesNamedScope()
并不也暗示InNamedScope()
,而是在我请求根时创建了一个新的根对象.
In my application I am using Ninject and the NamedScopeExtension. One of the objects deeper in the object graph needs access to the root object that defined the named scope. It seems to me that DefinesNamedScope()
does not also imply InNamedScope()
and instead a new root object is created when I request the root.
示例:
using System;
using Ninject;
using Ninject.Extensions.NamedScope;
using Ninject.Syntax;
namespace NInjectNamedScope
{
public interface IScopeRoot
{
Guid Guid { get; }
void DoSomething();
}
public interface IFactory
{
Guid Guid { get; }
IOther CreateOther();
}
public interface IOther
{
void SayHello();
}
internal class ScopeRoot : IScopeRoot
{
private readonly IFactory m_factory;
private readonly IResolutionRoot m_kernel;
public Guid Guid { get; private set; }
public ScopeRoot(IFactory factory, IResolutionRoot kernel)
{
m_factory = factory;
m_kernel = kernel;
Guid = Guid.NewGuid();
}
public void DoSomething()
{
Console.WriteLine("ScopeRoot.DoSomething(): Entering");
Console.WriteLine("ScopeRoot GUID: {0}", Guid);
Console.WriteLine("IFactory GUID: {0}", m_factory.Guid);
var other = m_factory.CreateOther();
Console.WriteLine("ScopeRoot.DoSomething(): Other created");
other.SayHello();
Console.WriteLine("ScopeRoot.DoSomething(): Exiting");
}
}
internal class Factory : IFactory
{
private IResolutionRoot m_kernel;
public Guid Guid { get; private set; }
public Factory(IResolutionRoot kernel)
{
m_kernel = kernel;
Guid = Guid.NewGuid();
}
public IOther CreateOther()
{
return m_kernel.Get<IOther>();
}
}
internal class Other : IOther
{
private readonly IScopeRoot m_root;
private readonly IFactory m_factory;
public Other(IScopeRoot root, IFactory factory)
{
m_root = root;
m_factory = factory;
}
public void SayHello()
{
Console.WriteLine("Other.SayHello(): Hello");
Console.WriteLine("Our IScopeRoot has GUID: {0}", m_root.Guid);
Console.WriteLine("Our IFactory has GUID: {0}", m_factory.Guid);
}
}
public class MainClass
{
public static void Main(string[] args)
{
var kernel = new StandardKernel();
kernel.Bind<IScopeRoot>().To<ScopeRoot>().DefinesNamedScope("RootScope");
kernel.Bind<IFactory>().To<Factory>().InNamedScope("RootScope");
kernel.Bind<IOther>().To<Other>().InNamedScope("RootScope");
var root = kernel.Get<IScopeRoot>();
root.DoSomething();
Console.ReadKey();
}
}
}
在此示例中,Other
正在接收与根相同的Factory
实例,但是会创建一个新的ScopeRoot
实例,而不是注入定义定义范围的现有实例.
In this example, Other
is receiving the same instance of Factory
as the root does, but a new instance of ScopeRoot
is created instead of injecting the existing instance that defined the named scope.
如何在工厂中访问命名范围的根?请注意,此示例已简化.实际上,作用域根目录和工厂方法之间有几层对象,因此我不能简单地将this
传递给工厂.
How can I access the root of the named scope in a factory? Please note that this example is simplified. In reality, there are several layers of objects between the scope root and the factory method, so I cannot simply pass this
to the factory.
推荐答案
是的,没错,Ninject无法执行.DefinesNamedScope().InNamedScope()
.除了后期的创建"(工厂,懒惰),这还是行不通的,因为这会产生周期性的依赖关系.
Yes you're right, out of the box Ninject can't do .DefinesNamedScope().InNamedScope()
. Except maybe for late "creation" (factory, lazy) this couldn't work anyway, because it would create a cyclic dependency.
实现所需目标的最简单方法是创建根目录的根目录" ...只有一个与DefinesNamedScope()
绑定并获得IRootScope
注入的类ActualRoot
,这又将是与.InNamedScope()
绑定.不好的是,您需要注入/Get<>
一个ActualRoot
而不是一个IRootScope
.
The simplest way to achieve what you want is to create a "root of the root"... well just one class ActualRoot
which is bound with DefinesNamedScope()
and gets an IRootScope
injected, which again will be bound with .InNamedScope()
. The bad thing about this is, that you will need to inject/Get<>
an ActualRoot
instead of a IRootScope
.
据我所记得,您还可以做的是:
As far as i remember, what you can also do instead, is:
Bind<IRootScope>().To<RootScope>()
.InNamedScope(scopeName);
,然后按以下方式检索它:
and then retrieve it as follows:
IResolutionRoot.Get<IRootScope>(new NamedScopeParameter(scopeName));
这样,您就不需要DefinesNamedScope()
.
这篇关于Ninject:如何从工厂访问NamedScope的根对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!