Castle.Windsor - 为什么名称需要与界面类似?

时间:2017-02-08 15:48:38

标签: c# asp.net-mvc castle-windsor hangfire

在我的ASP.NET MVC应用程序中尝试创建新的HangFire作业时,我注意到了这个有趣的场景。

// this is the interface for the HangFire job.
public interface ICsvExportService
{
    void ExportCsvToEmail();
}

// this is the implementation of the above interface.
public class ExportService : ICsvExportService
{
// code goes here.
}


RecurringJob.RemoveIfExists("My CSV exports");
        RecurringJob.AddOrUpdate<ICsvExportService>(
            "Send CSV exports",
            x => x.ExportCsvToEmail(),
            Cron.Daily(8));

当我尝试在本地测试时,我收到以下错误:

抛出异常:&#34; Castle.MicroKernel.ComponentNotFoundException&#34;在HangFire.Core.dll中 未找到支持服务ICsvExportService的组件。

尝试不同的解决方案30分钟后,我重命名了文件:ExportService to CsvExportService,魔术发生了!它奏效了!

有人可以解释为什么我需要使用与界面相同的名称才能使DI容器识别实际的实现类?

对于.NET 4.5,Castle.Core版本为3.3.3 对于.NET 4.5,Castle.Windsor版本为3.3.0

注册代码如下:

container.Register(
            Classes.FromThisAssembly()
                .Where(type => type.Name.EndsWith("Service"))
                .WithServiceDefaultInterfaces()
                .Configure(c => c.LifestyleTransient()));

非常感谢。

1 个答案:

答案 0 :(得分:8)

您没有显示您是如何注册接口和类的,但您可能正在使用DefaultInterfaces约定。

  

此方法根据类型名称和接口名称执行匹配。通常你会发现你有这样的接口/实现对:ICustomerRepository / CustomerRepositoryIMessageSender / SmsMessageSenderINotificationService / DefaultNotificationService 。在这种情况下,您可能希望使用DefaultInterfaces方法来匹配您的服务。它将查看所​​选类型实现的所有接口,并将其用作具有匹配名称的类型服务。匹配名称,意味着实现类在其名称中包含接口的名称(前面没有 I )。

有许多不同的约定,但您可能只是在寻找AllInterfaces

  

当组件实现多个接口并且您希望将其用作所有接口的服务时,请使用WithService.AllInterfaces()方法。