在我的应用程序中,我使用的是Ninject和NamedScopeExtension。对象图中更深层次的对象之一需要访问定义命名范围的根对象。在我看来,DefinesNamedScope()
并不暗示InNamedScope()
,而是在我请求根时创建了新的根对象。
示例:
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
正在接收与root相同的Factory
实例,但是创建了ScopeRoot
的新实例,而不是注入定义了named的现有实例范围。
如何在工厂中访问指定范围的根目录?请注意,此示例已简化。实际上,范围根和工厂方法之间有几层对象,所以我不能简单地将this
传递给工厂。
答案 0 :(得分:2)
是的,你是对的,开箱即用的Ninject不能.DefinesNamedScope().InNamedScope()
。除了可能是晚期&#34;创造&#34; (工厂,懒惰)无论如何都无法工作,因为它会产生循环依赖。
实现你想要的最简单的方法是创建一个&#34; root的根&#34; ...只是一个与ActualRoot
绑定的类DefinesNamedScope()
并得到一个IRootScope
注入,再次与.InNamedScope()
绑定。关于这一点的坏处是,您需要注入/ Get<>
ActualRoot
而不是IRootScope
。
据我记忆,你也可以做的是:
Bind<IRootScope>().To<RootScope>()
.InNamedScope(scopeName);
然后按如下方式检索它:
IResolutionRoot.Get<IRootScope>(new NamedScopeParameter(scopeName));
这样您就不需要DefinesNamedScope()
。