2016-02-15 160 views
8

我正在玩弄新的ASP.NET核心,目前正在创建一个我想从JavaScript前端调用的API。MediatR与ASP.NET核心DI

我想使用介体模式来减少耦合,并且我发现Jimmy Bogard的Library MediatR

我的问题在于使用DI构建接线,我尝试过看examples,但看不到它如何绑定到启动类中的ConfigureServices方法。

有没有人有任何见解?

更新:我得到它的工作,从我ConfigureService方法:

services.AddScoped<SingleInstanceFactory>(p => t => p.GetRequiredService(t)); 

services.Scan(scan => scan 
     .FromAssembliesOf(typeof(IMediator), typeof(MyHandler.Handler)) 
     .AddClasses() 
     .AsImplementedInterfaces()); 
+1

https://github.com/jbogard/MediatR/blob/master/samples/MediatR.Examples.AspNetCore/Program.cs似乎相当对我来说很简单,但是对于程序集扫描,您需要此Scrutor软件包(ASP.NET Core的DI不带有程序集扫描,并且没有计划发布它) – Tseng

+0

如何将它添加到ConfigureService方法? 'services.AddTransient(typeof(IMediator),BuildMediator()。GetType());' – Nyegaard

+1

你不想以这种方式注册它,Transient意味着它将在每次解析依赖时被创建。 'services.AddScoped (p => t => p.GetRequiredService(t));'和'services.AddScoped (p => t => p.GetRequiredServices(t));'工厂方法(多)或请求(单个) – Tseng

回答

16

截至7月2016年,吉米·博加德,MediatR的作者已经发布了一个包注册MediatR,和处理程序,与ASP.Net核心DI服务(这实际上是接口IServiceCollection,在Microsoft.Extensions.DependencyInjection实现,这是不仅限于在ASP.Net Core中使用)。

MediatR.Extensions.Microsoft.DependencyInjection

Link to GitHub Project

Link to NuGet Package information

博客文章引入包和它的能力,可以发现here

实施例登记直接从(很短)的博客文章复制:

public void ConfigureServices(IServiceCollection services) 
{ 
    services.AddMvc(); 

    services.AddMediatR(typeof(Startup)); 
} 

此包执行若干功能,以使MediatR,包括对处理程序所需的扫描程序集:

您可以传入处理程序所在的程序集,或者您可以从这些处理程序所在的程序集中传入Type对象。该扩展会将IMediator接口添加到您的服务,所有处理程序和正确的委托工厂以加载处理程序。然后在你的控制器,你可以只使用一个IMediator依赖性:

public class HomeController : Controller 
{ 
    private readonly IMediator _mediator; 

    public HomeController(IMediator mediator) 
    { 
    _mediator = mediator; 
    } 
    public IActionResult Index() 
    { 
    var pong = _mediator.Send(new Ping {Value = "Ping"}); 
    return View(pong); 
    } 
} 
+2

这应该是正确的答案。它不仅更优雅,更简单,而且是Mediatr创建者推荐的产品。 – reydelleon

+1

嗯,StackOverflows的政策是,'正确答案'是由问题提出者选择的人,他们认为解决了他们的特定问题。通过强调后来的答案或更广泛有用的答案引起人们的注意。不过,我希望人们在一个小时内停止回答自己的问题,并且实际上给人们一个回答的机会。有很多不正确的,差的或过时的答案,旁边有绿色的滴答声;我建议人们阅读所有答案,并确定哪些答案适合他们,并注意发布日期。 – dmcquiggin

+0

不幸的是,只有处理程序是公共类才能使用库。例如,如果使用内部作用域可见性定义它不起作用 – Lorenzo

2

我得到它的工作,我的代码:

public void ConfigureServices(IServiceCollection services) 
{ 
     services.AddScoped<SingleInstanceFactory>(p => t => p.GetRequiredService(t)); 
     services.AddScoped<MultiInstanceFactory>(p => t => p.GetRequiredServices(t)); 
     services.Scan(scan => scan 
       .FromAssembliesOf(typeof(IMediator), typeof(MyHandlerOne.Handler)) 
       .FromAssembliesOf(typeof(IMediator), typeof(MyHandlerTwo.Handler)) 
      .AddClasses() 
      .AsImplementedInterfaces()); 
} 

,我有一个实现了GetRequiredService是MultiInstanceFactory需要一个类:

public static class GetServices 
{ 
    public static IEnumerable<object> GetRequiredServices(this IServiceProvider provider, Type serviceType) 
    { 
     return (IEnumerable<object>)provider.GetRequiredService(typeof(IEnumerable<>).MakeGenericType(serviceType)); 
    } 
} 
0

我创建了一个DI helper for ASP.NET Core RC2哟你可以添加到你的启动。它给你基本的约定基于映射,所以如果你有这样一个类:

MyClass : IMyClass 

将在IOC容器,这将使其可用于注射映射IMyClass。

我还添加了MediatR的映射。

要使用它,只需将该类添加到您的项目,然后在你的startup.cs类添加你需要的ConfigureServices线()方法:

public void ConfigureServices(IServiceCollection services) 
{ 
    //Other Code here...... 

    var ioc = new PearIoc(services); 

    //ioc.AddTransient<IEmailSender, AuthMessageSender>(); 
    //ioc.AddTransient<ISmsSender, AuthMessageSender>(); 

    ioc.WithStandardConvention(); 
    ioc.WithMediatR(); 
    ioc.RunConfigurations(); 
} 

我增加了AddTransient()方法只是方便(你也可以使用services.AddTransient()),但它也暴露了IServiceCollection,以防你需要做更多的事情。

您也可以像扩展名为.WithMediatR()的扩展一样扩展它,并编写自己的自定义映射。