在不使用 Castle Windsor 注册的情况下解析类

发布于 2024-07-13 02:08:53 字数 711 浏览 4 评论 0原文

以下面这个无用的程序为例:

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 内部行为,请求尚未注册的类。

我宁愿让 Windsor 表现得像 Unity,而不是为 Prism 查找并注册所有这些类。 我在谷歌上没有找到任何东西可以帮助我做到这一点(尽管我的术语可能是错误的)并且温莎文档非常糟糕......

任何人都可以建议解决这个问题的方法吗?

Take the following useless program:

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>();
    }
}

The UnityContainer will return me an instance of Program, where as the Windsor container will throw a ComponentNotFoundException.

I can see arguments for both behaviours and don't mind which I end up with, however Prism V2 Drop 8 (the latest at time of writing) relies on the Unity behaviour internally, requesting classes that haven't been registered.

Rather than find and register all these classes for Prism I'd much rather just make Windsor behave like Unity. I haven't found anything on google to help me do this (although my terminology may be wrong) and the Windsor documentation is quite bad...

Can anyone suggest a solution to this problem?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

野の 2024-07-20 02:08:54

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;
    }
}

Krzysztof don't be afraid to link to your own blog here :) http://devlicious.com/blogs/krzysztof_kozmic/archive/2009/11/16/castle-windsor-lazy-loading.aspx

Also, I found this simple implementation useful in my WPF app, remove the string contraint and you are close to the general case

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;
    }
}
Bonjour°[大白 2024-07-20 02:08:53

Windsor 目前不支持这一点,这是设计使然。 原因是您应该显式注册所需的类型,这样就不会得到错误配置的对象。

然而,有可能在不久的将来的某个时候添加一个钩子来创建非注册类型,因为 WCF 集成工具需要这样做。 (编辑 - 它是在 v2.1 中添加的 - 看看 ILazyComponentLoaders)

无论如何,无论惰性组件加载器如何,你能做的最好的就是使用 Fluent API预先批量注册符合您所需标准的程序集中的所有类型。 不需要更多的代码,您晚上就会睡得更好。

仅当您在启动时确实没有足够的信息(在您的组合根中)来确定您需要哪些组件时,才使用惰性加载程序。

Windsor currently does not support that, and it's by design. The reasoning is that you should explicitly register types you need so that you dont get misconfigured object.

There is however a possibility that there will be added a hook to create non-registered type at some point in the near future, as this is needed by the WCF integration facility. (Edit - it was added in v2.1 - take a look at ILazyComponentLoaders)

Anyway, regardless of lazy component loaders, the best you can do is to use fluent API to batch register all types from an assembly matching your needed criteria upfront. It's not much more code and you'll sleep better at nights.

Use lazy loaders only if you have really not enough information at startup (in your composition root) to determine what components you'll need.

剩一世无双 2024-07-20 02:08:53

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>();
    }
}

Windsor doesn't support that out of the box, but you can create extension methods to do this:

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>();
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文