请参阅@samy回答,但这是不正确的公开课。我只需要改变:
StockDelayModule<T> : ModulePartBase<T>, IModulePart<T> where T : StockDelay
到
StockDelayModule : ModulePartBase<StockDelay>, IModulePart<StockDelay>
然后在StockDelayModule
到StockDelay
然后AsFactory()
注册正常工作,可以解析正确的组件。
我一直不愿意发布这个问题,因为我想弄明白,但我也不想发表一些“重复”的评论,但我不知所措。
我有一个界面
public interface IModulePart<T>
{
IResponse<T> Create(CreateRequest request, IPromise<T> promise);
IResponse Delete(DeleteRequest request, IPromise<T> promise);
IResponse<T> Read(ReadRequest request, IPromise<T> promise);
IResponse<T> Update(UpdateRequest request, IPromise<T> promise);
}
有几个实现因T
而异。例如:
WebUrlModule<T> : IModulePart<T> where T : WebUrl
StockDelayModule<T> : IModulePart<T> where T : StockDelay
我有我的安装程序,它正在注册组件:
Classes.FromAssemblyInDirectory(new AssemblyFilter("bin"))
.BasedOn(typeof(IModulePart<>))
.WithService.Base()
.LifestyleTransient()
我有我的工厂:
public interface IModulePartFactory
{
IModulePart<T> FindModulePartFor<T>();
}
然后我的工厂选择器正在运行,从GetComponentType
覆盖DefaultTypedFactoryComponentSelector
:
protected override Type GetComponentType(MethodInfo method, object[] arguments)
{
if (method.Name == "FindModulePartFor")
{
return typeof(IModulePart<>).MakeGenericType(method.GetGenericArguments()[0]);
}
return base.GetComponentType(method, arguments);
}
每件事似乎看起来大多是正确的,并且在调试时(使用WebUrl
),泛型类型就像IModulePart'1[[WebUrl, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]
但是,正如您可能已经猜到的那样,它无效。如果我使用StockDelay
拨打电话,它会解决问题,因为我认为它会返回第一个注册的组件,但是当使用WebUrl
时,它会中断。我说StockDelay
有效,但我认为它更多的是它返回任何东西(第一个匹配的组件),而不是选择正确的组件。
我得到的信息是:
Types WebUrl don't satisfy generic constraints of implementation type StockDelayModule'1 of component 'StockDelayModule'1'. This is most likely a bug in your code.
对任何人来说,任何明显的东西,或对可能不正确的任何事情的建议?或者我只是尝试一些不可能的事情!?感谢。
如果我将我的类更改为抽象并使用非泛型的派生类实现它,则可以正常工作。因此,我认为它只是城堡中与通用相关的一个小配置,这意味着它无法正确解析。想法:
public class StockDelayModule : StockDelayModulePart<StockDelay> { }
public abstract class StockDelayModulePart<T> : ModulePartBase<T>, IModulePart<T> { }
答案 0 :(得分:1)
您不需要自定义解析程序,因为Castle会尝试根据返回类型解析工厂调用。除非您需要其他一些内容,否则以下内容应足以根据IModulePart<T>
解析T
:
public class WebUrl { }
public class StockDelay { }
public interface IModulePart<T> { }
public class WebUrlModule : IModulePart<WebUrl> { }
public class StockDelayModule : IModulePart<StockDelay> { }
public interface IModulePartFactory
{
IModulePart<T> FindModulePartFor<T>();
}
internal class Program
{
private static void Main(string[] args)
{
var container = new Castle.Windsor.WindsorContainer();
container.AddFacility<TypedFactoryFacility>();
container.Register(
Classes.FromAssemblyInThisApplication()
.BasedOn(typeof(IModulePart<>))
.WithService.Base()
.LifestyleTransient(),
Component.For<IModulePartFactory>().AsFactory()
);
var factory = container.Resolve<IModulePartFactory>();
var moduleForWebUrl = factory.FindModulePartFor<WebUrl>();
// type is WebUrlModule
var moduleForStockDelay = factory.FindModulePartFor<StockDelay>();
// type is StockDelayModule
}
}
答案 1 :(得分:0)
如果您尝试覆盖其他方法会发生什么:
protected override string GetComponentName(MethodInfo method,object [] arguments)
容器注册说什么?您可以使用配置错误的组件检查注册和部分。
虽然重写此方法可能部分解决了问题,但它无法解决问题的根源 - 这是检查组件配置是否错误的另一种方法。