HO通过课程传播AutoFac范围/容器?

发布于 2025-02-10 18:43:53 字数 1400 浏览 1 评论 0原文

传播AutoFac容器以从不同类访问并访问它的正确方法是什么?

我理解文档的方式,我将每个类添加为构造函数参数,如果AUTOFAC也解决了调用类,则将注入范围(不确定在此上下文中注入正确的术语)。

例子: program.cs

using Autofac;

namespace HelloWorld
{
    public class Program
    {
        private static IContainer Container { get; set; }

        static void Main(string[] args)
        {
            Console.WriteLine("Hello, World!");

            var builder = new ContainerBuilder();
            builder.RegisterType<Class1>();
            builder.RegisterType<Class2>();
            Container = builder.Build();

            var obj1 = Container.Resolve<Class1>();
            obj1.Write();
        }
    }
}

class1.cs

using Autofac;

namespace HelloWorld
{
    internal class Class1
    {
        public Class1(ILifetimeScope scope)
        {
            _scope = scope.BeginLifetimeScope();
        }
        public void Write()
        {
            var class2 = _scope.Resolve<Class2>();
            class2.Write();
        }

        private readonly ILifetimeScope _scope;
    }
}

class2.cs

namespace HelloWorld
{
    internal class Class2
    {
        public void Write()
        {
            Console.WriteLine("Hello, I'm class 2.");
        }
    }
}

输出:
你好,世界!
您好,我是2级。

这个示例有效,但是,我觉得范围的处理方式和手动解决方案是开销。那么这是使用AutoFac的预期方法吗?

What's the correct way to propagate the autofac container to and access it from different classes?

The way I understand the documentation, I add the scope to each class as constructor argument and if the calling class was also resolved by autofac, the scope will be injected (not sure if injected is the right term in this context).

Example:
Program.cs

using Autofac;

namespace HelloWorld
{
    public class Program
    {
        private static IContainer Container { get; set; }

        static void Main(string[] args)
        {
            Console.WriteLine("Hello, World!");

            var builder = new ContainerBuilder();
            builder.RegisterType<Class1>();
            builder.RegisterType<Class2>();
            Container = builder.Build();

            var obj1 = Container.Resolve<Class1>();
            obj1.Write();
        }
    }
}

Class1.cs

using Autofac;

namespace HelloWorld
{
    internal class Class1
    {
        public Class1(ILifetimeScope scope)
        {
            _scope = scope.BeginLifetimeScope();
        }
        public void Write()
        {
            var class2 = _scope.Resolve<Class2>();
            class2.Write();
        }

        private readonly ILifetimeScope _scope;
    }
}

Class2.cs

namespace HelloWorld
{
    internal class Class2
    {
        public void Write()
        {
            Console.WriteLine("Hello, I'm class 2.");
        }
    }
}

Output:
Hello, World!
Hello, I'm class 2.

This example works, however, I feel like the handling of the scope and the manual resolving is quite the overhead. So is this the intended way to use autofac?

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

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

发布评论

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

评论(1

冰葑 2025-02-17 18:43:53

这里有两个问题。首先是如何通过课程传播范围,这是字面问题;但是第二个更隐含,关于您实际要做的事情。

第一个问题 - 您如何通过课程传播范围? :您对此有正确的想法。如果要访问解决对象的生命周期范围,则添加ilifetimesCope属性,并且可以使用它来执行服务位置。

第二个问题 - 这是使用AutoFac? 的预期方法:这实际上比AutoFac要大。您需要做的是查看哪些“依赖注入”和“控制倒置”是什么。这些不是特定于AutoFac的模式。

通常,您不应该做服务位置。换句话说,您几乎应该永远不需要注入终身范围并尝试解决手动的东西。在有趣的边缘案例中,该规则有例外,但这就是为什么我通常会说 是这种情况。

一般而言,您应该只添加所需的构造函数参数。这是控制容器反转的全部点(在这种情况下为AUTOFAC) - 它查看您的构造函数并为您完成所有Resolve新的调用。

autofac文档中有一个很棒的入门指南显示了您如何构建应用程序的基本演练。我强烈建议您浏览这些文档,还花一些时间来研究依赖注入。当您搜索时,请考虑不要将“ AUTOFAC”专门放在搜索术语列表中,因为该模式比AutoFac甚至.NET大得多 - 它是一种一般的编程模式。

为了非常特定于示例,您将更改class1,以免使用服务位置。 AutoFac处理电线。

namespace HelloWorld
{
    internal class Class1
    {
        public Class1(Class2 class2)
        {
            // Autofac sees this and automatically resolves
            // it from the lifetime scope.
            _class2 = class2;
        }
        public void Write()
        {
            this._class2.Write();
        }

        private readonly Class2 _class2;
    }
}

There are sort of two questions here. The first is how to propagate scope through classes, which is sort of the literal question; but the second is more implicit, about what you're actually trying to do.

The first question - How do you propagate scope through classes?: You have the right idea for this. If you want to access the lifetime scope from which an object was resolved, you add an ILifetimeScope property and you can use that to do service location if you need to.

The second question - Is this the intended way to use Autofac?: This is actually larger than Autofac. What you need to do is look at what "dependency injection" and "inversion of control" are. These aren't Autofac-specific patterns.

In general, you shouldn't do service location. Put another way, you should almost never need to inject a lifetime scope and try to resolve something manually. There are exceptions to the rule in interesting edge cases, but that's why I say in general this is the case.

In general, you should just add the constructor parameters you need. That's the whole point of the inversion of control container (in this case, Autofac) - it looks at your constructors and does all the Resolve and new calls for you.

There is a great getting started guide in the Autofac docs that shows the basic walkthrough of how you structure your app. I would strongly encourage you to go through those docs and also take some time to research dependency injection. As you search, consider not putting "Autofac" specifically in the list of search terms, since the pattern is much bigger than Autofac, or even .NET - it's a general programming pattern.

To get very specific to your example, you'd change your Class1 so it doesn't do service location. Autofac handles the wire-up.

namespace HelloWorld
{
    internal class Class1
    {
        public Class1(Class2 class2)
        {
            // Autofac sees this and automatically resolves
            // it from the lifetime scope.
            _class2 = class2;
        }
        public void Write()
        {
            this._class2.Write();
        }

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