Autofac:如何在依赖于另一个对象函数输出的类上使用构造注入

发布于 2024-11-01 02:58:26 字数 790 浏览 2 评论 0原文

这个问题一般是关于 IoC 的,但我使用的是 Autofac,所以 Autofac 解决方案会很棒。

因此,假设以下类:

class A
{
    IEnumerable<B> GetBs();
}

class B 
{
    // Some code
}

class C
{
    readonly IEnumerable<B> bs;

    C(IEnumerable<B> bs)
    {
        this.bs = bs;
    }
}

class Program
{
    static void Main(string[] args)
    {
        var builder = new ContainerBuilder();
        builder.Register<A>();
        builder.Register<C>();

        var container = builder.Build();
        var c = container.Resolve<C>();
        // do something with c
    }
}

上面的 Main 将失败。

我注意到我可以通过添加这行代码来解决这个问题:

builder.Register(c => c.Resolve<A>().GetBs())

但是,这感觉不对。还有其他方法可以实现这一目标吗?还是设计改变?

This question is about IoC in general, but I'm using Autofac, so an Autofac solution would be great.

So assume the following classes:

class A
{
    IEnumerable<B> GetBs();
}

class B 
{
    // Some code
}

class C
{
    readonly IEnumerable<B> bs;

    C(IEnumerable<B> bs)
    {
        this.bs = bs;
    }
}

class Program
{
    static void Main(string[] args)
    {
        var builder = new ContainerBuilder();
        builder.Register<A>();
        builder.Register<C>();

        var container = builder.Build();
        var c = container.Resolve<C>();
        // do something with c
    }
}

the above Main will fail.

I've noticed that I can solve this by adding this line of code:

builder.Register(c => c.Resolve<A>().GetBs())

However, that doesn't feel right. Any other way to achieve this? Or design changes?

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

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

发布评论

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

评论(2

一袭白衣梦中忆 2024-11-08 02:58:26

正如所给出的,这个类结构看起来非常好。您正确使用构造函数注入并使用类的静态结构来传达不变量和关系。在此处提供的信息级别上,我认为唯一缺少的是 C 构造函数中的 Guard Clause :)

在概念级别上,很难回答这是否是一个好的设计。这取决于此处未提供的上下文。 B 是服务还是实体? Bs 的预期来源是什么?

作为一般经验法则,我们应该只注入服务,但处理具有服务的实体(例如存储库或网关等),因此如果 B 代表服务,则可以将其注入到 C 中。如果它代表实体,则它变得可疑 - 除非 C 也是一个实体...

另一方面,您可以询问 B 的规范来源。如果 A 确实是 B 的容器,那么上述解决方案是正确的(也是惯用的 Autofac 代码)。如果 B 确实有不同的起源,那么通过 A 解决它们可能是一个黑客......

As given, this class structure looks perfectly fine. You are properly using Constructor Injection and using the static structure of the classes to communicate invariants and relationships. On the level of information provided here, I think the only thing missing is a Guard Clause in the C constructor :)

On a conceptual level it's harder to answer whether or not this is a good design. That depends on context not provided here. Is B a Service or an Entity? What is the intended source of Bs?

As a general rule of thumb we should only inject Services, but handle Entities with Services (such as Repositories or Gateways or whatnot), so if B represents a Service it would be okay to inject it into C. If it represents an Entity, then it becomes suspect - unless C is also an Entity...

On another note you can ask about the canonical source of Bs. If A truly is meant to be the container of Bs, then the above solution is correct (and idiomatic Autofac code). If the Bs really have a different origin, resolving them through A may be a hack...

一梦浮鱼 2024-11-08 02:58:26

鉴于您对已接受答案的答复,Autofac 中可能会使用另一种技术。如果注册期间可以使用这组插件,您可以将它们注册为集合

Given your reply to the accepted answer, there might be another technique to use in Autofac. If the set of plugins is available during registration, you could register them as a collection.

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