项目计划以多平台为目标,因此我在类库中提取了最多的代码,以便可以轻松地重复使用。
该架构基于Model-View-Presenter原则。
项目结构如下:
Solution
-> Domain
-> Domain.Tests
-> MVP
-> MVP.Tests
-> Web
-> Web.Tests
-> Windows
-> Windows.Tests
MVP
此项目包含演示者和项目的视图。例如:
public interface IApplicationView : IView, IHasUiHandler<IApplicationUiHandler> {
}
public class ApplicationPresenter : Presenter<IApplicationView>
, IApplicationUiHAndler {
public ApplicationPresenter(IApplicationView view) : base(view) {
View.Handler = this;
}
}
窗
该项目包含应用程序的WPF GUI和所谓的Composition Root。例如:
public class ApplicationWindow : Window, IApplicationView {
}
public class App : Application {
protected override void OnStartUp(StartupEventArgs e) {
IKernel kernel = new StandardKernel();
kernel.Bind(x => x
.FromThisAssembly()
.SelectAllClasses().EndingWith("Window")
.BindAllInterfaces().EndingWith("View") // Here's what I'd like to do.
);
}
}
网络
此项目包含应用程序的ASP.NET GUI页面和所谓的Composition Root。
public class ApplicationPage : Page, IApplicationView {
}
public class MvcApplication : HttpApplication {
protected override void Application_Start() {
IKernel kernel = new StandardKernel();
kernel.Bind(x => x
.FromThisAssembly()
.SelectAllClasses().EndingWith("Page")
.BindAllInterfaces().EndingWith("View") // Here's what I'd like to do.
}
}
嗯,我想你明白了......
我对依赖注入很新,甚至更新于约定。
我想知道如何使用Ninject使用约定来配置绑定。
知道如何用Windows(WPF)和Pages(Web)绑定这些视图吗?
修改
在尝试了@BatteryBackupUnit建议之后,我想我的问题就是我对程序集的搜索。
using (var kernel = new StandardKernel())
kernel.Bind(scanner => scanner
.From(AppDomain.CurrentDomain
.GetAssemblies()
.Where(a => (a.FullName.Contains("MyProject.MVP")
|| a.FullName.Contains("Windows"))
&& !a.FullName.Contains("Tests")))
.SelectAllClasses()
.EndingWith("Window")
.BindSelection((type, baseType) =>
type.GetInterfaces().Where(iface => iface.Name.EndsWith("View"))));
如前所述,View
接口与Window
类不在同一个程序集中。上面的代码基于@ BatteryBackupUnit的答案,效果很好。
答案 0 :(得分:1)
这个怎么样:
using FluentAssertions;
using Ninject;
using Ninject.Extensions.Conventions;
using System.Linq;
using Xunit;
public interface ISomeView { }
public interface ISomeOtherView { }
public interface INotEndingWithViewWord { }
public class SomePage : ISomeView, ISomeOtherView, INotEndingWithViewWord
{
}
public class Demo
{
[Fact]
public void Test()
{
using (var kernel = new StandardKernel())
{
kernel.Bind(x => x
.FromThisAssembly()
.SelectAllClasses()
.EndingWith("Page")
.BindSelection((type, baseType) =>
type.GetInterfaces()
.Where(iface => iface.Name.EndsWith("View"))));
kernel.Get<ISomeView>().Should().BeOfType<SomePage>();
kernel.Get<ISomeOtherView>().Should().BeOfType<SomePage>();
kernel.Invoking(x => x.Get<INotEndingWithViewWord>())
.ShouldThrow<ActivationException>();
}
}
}
注意:我一直在使用nuget包
那些xunit.net和FluentAssertions仅用于运行测试而不用于生产。
或者您也可以使用.BindWith<T : IBindingGenerator>
或.BindUsingRegex(...)
。