0

这些项目计划针对多平台,所以我在类库中提取了最大的代码,以便它可以轻松重用。

该架构基于模型-视图-演示者原则。

项目结构如下:

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 的回答,效果很好。

4

1 回答 1

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 包

  • 忍者
  • Ninject.Extensions.Conventions
  • xunit.net
  • 流利的断言

其中的 xunit.net 和 FluentAssertions 仅用于运行测试而不用于生产。

或者你也可以使用.BindWith<T : IBindingGenerator>or .BindUsingRegex(...)

于 2014-05-23T05:43:48.693 回答