采取以下无用程序:
class Program
{
static void Main(string[] args)
{
IUnityContainer unityContainer = new UnityContainer();
IWindsorContainer windsorContainer = new WindsorContainer();
Program unityProgram = unityContainer.Resolve<Program>();
Program castleProgram = windsorContainer.Resolve<Program>();
}
}
UnityContainer将返回一个Program实例,其中Windsor容器将抛出ComponentNotFoundException。
我可以看到这两种行为的争论而不介意我最终会遇到什么,但是Prism V2 Drop 8(写作时的最新版本)依赖于内部的Unity行为,请求尚未注册的类。
而不是为Prism找到并注册所有这些类,而不仅仅是让Windsor表现得像Unity一样。我没有在谷歌找到任何帮助我这样做的东西(虽然我的术语可能是错的)而且Windsor文档非常糟糕......
有人可以建议解决这个问题吗?
答案 0 :(得分:9)
温莎目前不支持这一点,而且它是设计的。原因是你应该明确注册你需要的类型,这样你就不会得到配置错误的对象。
但是,有可能在不久的将来会在某个时刻添加一个钩子来创建非注册类型,因为这是WCF集成工具所需要的。 (编辑 - 它已在v2.1中添加 - 请查看ILazyComponentLoader
s)
无论如何,无论懒惰的组件加载器如何,您可以做的最好的事情就是使用流畅的API批量注册所有类型,从一个符合您所需条件的程序集中预先填写。这不是更多的代码,你晚上睡得更好。
只有在启动时(在组合根中)确实没有足够的信息来确定您需要的组件时才使用延迟加载器。
答案 1 :(得分:6)
Windsor不支持开箱即用,但您可以创建扩展方法来执行此操作:
static class WindsorExtensions
{
public static object ResolveType(this IWindsorContainer container, Type type)
{
if ( type.IsClass && !container.Kernel.HasComponent(type) )
container.Kernel.AddComponent(type.FullName, type, LifestyleType.Transient);
return container.Resolve(type);
}
public static T ResolveType<T>(this IWindsorContainer container)
{ return (T)ResolveType(container, typeof(T)); }
}
class Program
{
static void Main(string[] args)
{
IUnityContainer unityContainer = new UnityContainer();
IWindsorContainer windsorContainer = new WindsorContainer();
Program unityProgram = unityContainer.Resolve<Program>();
Program castleProgram = windsorContainer.ResolveType<Program>();
}
}
答案 2 :(得分:2)
Krzysztof不要害怕链接到您自己的博客:) http://devlicious.com/blogs/krzysztof_kozmic/archive/2009/11/16/castle-windsor-lazy-loading.aspx
另外,我发现这个简单的实现在我的WPF应用程序中很有用,删除字符串约束并且你接近一般情况
public class ViewModelLoader : Castle.MicroKernel.Resolvers.ILazyComponentLoader {
public IRegistration Load(string key, Type service)
{
if (service == null)
return null;
if (service.Name.EndsWith("ViewModel", StringComparison.CurrentCultureIgnoreCase))
return Component.For(service).Named(key);
else
return null;
}
}