我有一个MessageChannel接口,它定义了(不出所料)我的类可用于将消息推送给最终用户的通道。
通常,此MessageChannel是Singleton,并绑定到实现MessageChannel接口的ViewModel。从本质上讲,我的应用程序顶部有一个位置,用于显示给用户的消息。到目前为止,它的效果非常好。
此MessageChannel用于很多地方,其中一个位于我设置的某些操作类中。
我现在需要一个LOCAL MessageChannel,这些在一些缩小范围内发布的消息会发布到本地MessageChannel而不是全局消息。
这意味着我需要能够创建ViewModel的实例(通过Factory),以便该特定实例具有自己的MessageChannel实例,并且为注入该ViewModel的所有依赖项共享MessageChannel实例(和他们的依赖等等。)
一些类来说明。我稍微简化了一些事情,我的消息不仅仅是字符串:
using Ninject;
using Ninject.Extensions.Factory;
public interface MessageChannel
{
void PostMessage(string message);
}
public class MessageChannelViewModel : MessageChannel
{
public string Message { get; set; }
public void PostMessage(string message)
{
Message = message;
}
}
public interface Operation
{
void Do();
}
public interface OperationFactory
{
Operation Create();
}
public class DefaultOperation : Operation
{
public DefaultOperation(MessageChannel userMessages)
{
_UserMessages = userMessages;
}
private readonly MessageChannel _UserMessages;
public void Do()
{
// Do something.
_UserMessages.PostMessage("Success!");
}
}
public interface IsolatedViewModel
{
MessageChannelViewModel LocalMessages { get; }
}
public interface IsolatedViewModelFactory
{
IsolatedViewModel Create();
}
public class DefaultIsolatedViewModel : IsolatedViewModel
{
public IsolatedViewModel(MessageChannelViewModel localMessages, OperationFactory opFactory)
{
_OpFactory = opFactory;
LocalMessages = localMessages;
}
private readonly OperationFactory _OpFactory;
public MessageChannelViewModel LocalMessages { get; private set; }
}
public class Module : NinjectModule
{
public override void Load()
{
Bind<MessageChannel, MessageChannelViewModel>().To<MessageChannelViewModel>().InSingletonScope();
Bind<Operation>().To<DefaultOperation>();
Bind<OperationFactory>().ToFactory();
Bind<IsolatedViewModel>().To<DefaultIsolatedViewModel>();
Bind<IsolatedViewModelFactory>().ToFactory();
// Something to make it so the IsolatedViewModel DOESNT get the Singleton
// instance of the MessageChannelViewModel, and instead gets once of its own
// AND so the Operations created by the OperationFactory injected into the
// IsolatedViewModel get the SAME MessageChannel, so messages being posted
// from any place in the IsolatedViewModel's dependencies are shown only\
// locally.
}
}
我尝试过NamedScope扩展,但我无法按照我的意愿去做。
答案 0 :(得分:1)
我认为你可以尝试使用 The Ninject Context Preservation Extension ,它增加了对调用内核解析请求的工厂的上下文的记录(以及可用于上下文绑定规则)的支持。
这使您可以为Bindings添加上下文条件。
答案 1 :(得分:1)
我最终使用了Ninject.Extensions.ContextPreservation和Ninject.Extensions.NamedScope的组合来完成我想要的。
完成的示例模块如下所示:
public class Module : NinjectModule
{
public override void Load()
{
Bind<MessageChannel, MessageChannelViewModel>().To<MessageChannelViewModel>().InSingletonScope();
Bind<Operation>().To<DefaultOperation>();
Bind<OperationFactory>().ToFactory();
var uniqueName = "UNIQUE";
Bind<IsolatedViewModel>()
.To<DefaultIsolatedViewModel>()
.Named(uniqueName)
.DefinesNamedScope(uniqueName);
Bind<MessageChannel, MessageChannelViewModel>().To<MessageChannelViewModel>()
.WhenAnyAncestorNamed(uniqueName)
.InNamedScope(uniqueName);
Bind<IsolatedViewModelFactory>().ToFactory();
}
}
Theres的两个部分。
其他一些需要注意的事项: