Castle 无法解析所有已注册的组件

Sex*_*yMF 3 c# dependency-injection castle-windsor

我有以下课程。

public interface ICampaignDal : ICrudDal<Campaign>
{
}
public class CampaignDal : BaseDal<Campaign>, ICampaignDal
{
}

public interface IPixelDal : ICrudDal<Pixel>
{
}
public class PixelDal : BaseDal<Pixel>, IPixelDal
{
}


public interface ICrudDal<T> where T : BaseEntity, new()
{
}
Run Code Online (Sandbox Code Playgroud)

这就是我注册它们的方式:

Container.Register(
     Types.FromAssembly(typeof (ICrudDal<>).Assembly)
             .BasedOn(typeof (ICrudDal<>)).WithServiceAllInterfaces());
Run Code Online (Sandbox Code Playgroud)

当我解决这个问题时,它工作正常:

Container.Resolve<ICampaignDal>();
Run Code Online (Sandbox Code Playgroud)

但是这个:

Container.Resolve<IPixelDal>();
Run Code Online (Sandbox Code Playgroud)

会产生一个错误:

"Type DataAccessLayer.IPixelDal is abstract.\r\n As such, it is not possible to instansiate it as implementation of service 'DataAccessLayer.IPixelDal'. Did you forget to proxy it?"

Cri*_*scu 6

我使用以下代码检查了容器配置(受此答案启发):

foreach (var handler in c.Kernel.GetAssignableHandlers(typeof(object)))
    Console.WriteLine("{0} implemented by: {1}",
        String.Join(",", handler.ComponentModel.Services) ,
        handler.ComponentModel.Implementation);
Run Code Online (Sandbox Code Playgroud)

上面代码的输出是:

ConsoleApp.ICampaignDal,ConsoleApp.ICrudDal`1[ConsoleApp.Campaign] implemented by: ConsoleApp.CampaignDal
ConsoleApp.ICampaignDal,ConsoleApp.ICrudDal`1[ConsoleApp.Campaign] implemented by: ConsoleApp.ICampaignDal
ConsoleApp.ICrudDal`1[T] implemented by: ConsoleApp.ICrudDal`1[T]
ConsoleApp.ICrudDal`1[ConsoleApp.Pixel],ConsoleApp.IPixelDal implemented by: ConsoleApp.IPixelDal
ConsoleApp.ICrudDal`1[ConsoleApp.Pixel],ConsoleApp.IPixelDal implemented by: ConsoleApp.PixelDal
Run Code Online (Sandbox Code Playgroud)

如您所见,IPixelDal(最后两行)有两个注册。默认注册(两者中的第一个)表示它IPixelDal是由自己实现的。考虑到这是一个抽象类型(接口),无法实例化它,这一点已由您收到的错误消息证实。

我对你的代码做了一个简单的调整,它工作正常:

Container.Register(
        Types.FromAssembly(typeof(ICrudDal<>).Assembly)
                .BasedOn(typeof(ICrudDal<>))
                .Unless(t => t.IsAbstract)
                .WithServiceAllInterfaces());
Run Code Online (Sandbox Code Playgroud)

.Unless(t => t.IsAbstract)行指示容器仅自动注册具体类型。

免责声明:我不是 Castle Windsor 用户,所以我不确定这是否是惯用的解决方案。但如果您需要快速修复,它肯定有效。