Use*_*ser 7 .net mvp dependency-injection
我正在尝试使用依赖注入与MVP将所需的依赖项注入构造函数.我遇到的问题是,如果我在根MainWindowPresenter上使用依赖注入,所有它的子演示者及其子演示者,视图和服务都将在启动时加载.由于所有内容都是直接或间接从MainWindowPresenter加载的,这意味着整个应用程序将在启动时加载到内存中.
我知道在.NET中创建所有对象在启动时可能不会花费很多,但我不禁认为这是浪费内存,因为它们永远不会同时被使用.有一些像AboutPresenter或HelpPresenter可能永远不会被使用.我错过了或者这是依赖注入应该如何工作?有没有解决的办法?
我能找到解决这个问题的唯一方法是使用工厂,然后可以在需要时创建子演示者/视图/服务.例如:
class HelpFactory : AbstractHelpFactory
{
public IHelpPresenter Create()
{
IHelpService helpService = new ConcreteHelpService();
IHelpView helpView = new ConcreteHelpView();
HelpSearchPresenter searchPresenter = HelpSearchFactory.Create();
return HelpPresenter(helpView, helpService, searchPresenter);
}
}
Run Code Online (Sandbox Code Playgroud)
这与工厂当时依赖于子工厂基本相同,但至少它们比演示者/视图/服务更轻,并且他们不需要在需要之前加载子工厂.
有几种可能的解决方案(从一般到具体排列):
确定组合根。这是应用程序中模块组合在一起的(最好)唯一位置。这是组合所有依赖项的最佳解决方案。
您可以注入类似依赖项的工厂,而不是注入依赖项。这将帮助您推迟依赖项创建并仅解决当前情况所需的依赖项。使用ninject.extension.factory 的示例:
kernel.Bind<IDependencyFactory>().ToFactory();
kernel
.Bind<IDependency>()
.To<DependencyImpl1>()
.NamedLikeFactoryMethod((IDependencyFactory f) => f.GetJob());
var abstractFactory = kernel.Get<IDependencyFactory>();
var dependency = abstractFactory.GetJob();
public abstract class IDependency { }
public class DependencyImpl1 : IDependency { }
public interface IDependencyFactory
{
IDependency GetJob();
Lazy<IDependency> GetLazyJob();
}
Run Code Online (Sandbox Code Playgroud)
这也将有助于避免类的过度注入,例如构造函数过度注入
注入聚合处理例程的服务,而不是注入依赖项。阅读更多内容重构聚合服务
有时,由于启动期间创建成本过高和/或很少使用等原因,有必要推迟依赖项的解析。在这些情况下,可以注入 Lazy 来代替 IDependency。使用 Ninject.Extension.Factory 的示例:
kernel
.Bind<Lazy<IDependency>>()
.To<Lazy<IDependency>>()
.NamedLikeFactoryMethod((IDependencyFactory f) => f.GetLazyJob());
var abstractFactory = kernel.Get<IDependencyFactory>();
var lazyDependencyUsingFactory = abstractFactory.GetLazyJob();
Run Code Online (Sandbox Code Playgroud)
使用不带工厂的延迟加载的示例:
kernel
.Bind<IDependency>()
.To<DependencyImpl1>();
kernel
.Bind(typeof (Lazy<>))
.ToMethod(context =>
((ILazyLoader) Activator.CreateInstance(typeof (LazyLoader<>).MakeGenericType(context.GenericArguments),
new object[] { context.Kernel })).Loader);
var lazyDependency = kernel.Get<Lazy<IDependency>>();
lazyDependency.Dump();
lazyDependency.Value.Dump();
Run Code Online (Sandbox Code Playgroud)
ps:完整示例可在此处获取
归档时间: |
|
查看次数: |
463 次 |
最近记录: |