autofac 的使用与简单的 IoC 实现相比

发布于 2024-09-30 02:54:31 字数 851 浏览 4 评论 0原文

我目前正在使用/试验 autofac 作为我的 IoC 控制器。

在此之前,我使用了一个定义两个方法的简单静态类,类似于

public static TService Resolve<TService>()  
public static void Register<IType, ImpType>()

ImpType 必须是 IType 的情况。

现在转到 autofac。注册时,您可能会执行类似的操作

builder.RegisterType<ProductRepository>().As<IProductRepository>(); 

,但是如果 ProductRepository 不是 IProductRepository,您不会收到编译错误吗? 如果需要的话,是否有某种方法可以更安全地接线?

其次,在构建我的 Ioc 模块时,我使用类似

public static class IoCContainer
{
    public static IContainer BaseContainer { get; private set; }

    public static void Build(ContainerBuilder builder)
    {
        BaseContainer = builder.Build();            
    }
}

在调用 IoCContainer.Build(..) 之后我无法再将任何内容注册到 BaseContainer 中。将此与可以从任何地方注册任何内容的简单模型进行比较。也许这是设计使然?

I am currently using/experimenting with autofac as my IoC controller.

Previously to this I used a simple static class defining two methods, similar to

public static TService Resolve<TService>()  
public static void Register<IType, ImpType>()

where ImpType must be of IType.

Now over to autofac. When registering, you might do something like

builder.RegisterType<ProductRepository>().As<IProductRepository>(); 

however if ProductRepository is-not-a IProductRepository you don't get a compile error?
Is there some way of wiring things up more safely if desired?

Secondly, when building my Ioc modules I use something like

public static class IoCContainer
{
    public static IContainer BaseContainer { get; private set; }

    public static void Build(ContainerBuilder builder)
    {
        BaseContainer = builder.Build();            
    }
}

After I have called IoCContainer.Build(..) I can no longer register anything 'into' the BaseContainer. Compare this with the simple model where you can register anything from anywhere. Perhaps this is by design?

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

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

发布评论

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

评论(1

三生殊途 2024-10-07 02:54:31

我认为 .RegisterType.As 模式不是类型安全的,只是因为 C# 编译器(或 CLR 类型系统)不处理此类类型约束。例如,以下假设的 As 方法声明将无法编译:

interface IRegistration<TImplementation>
{
   void As<TContract>() where TImplementation : TContract;
}

编译器错误为“'SomeNamespace.IRegistration.As()' 未定义类型参数 'TImplementation'”。

如果需要的话,是否有某种方法可以更安全地接线?

以下内容似乎有效(尽管最佳实践部分不鼓励这样做) Autofac 维基)。除非 Foo 实现 IFoo,否则它将给出编译器错误:

     var builder = new ContainerBuilder();
     builder.Register<IFoo>(c => new Foo()).SingleInstance();

     var container = builder.Build();
     var foo = container.Resolve<IFoo>();

cIComponentContext。如果 Foo 构造函数需要构造函数参数,那么您可以编写 c =>; new Foo(c.Resolve()).

在调用 IoCContainer.Build(..) 之后,我无法再将任何内容注册到 BaseContainer

您可以 更新 Autofac 2.2 中的容器

I think the .RegisterType<Foo>.As<IFoo> pattern is not type safe simply because the C# compiler (or the CLR type system) does not handle such type constraints. For example, the following hypothetical declaration of the As method won't compile:

interface IRegistration<TImplementation>
{
   void As<TContract>() where TImplementation : TContract;
}

The compiler error is "'SomeNamespace.IRegistration.As()' does not define type parameter 'TImplementation'".

Is there some way of wiring things up more safely if desired?

The following seems to work (though it is discouraged by the best practices section on the Autofac wiki). It will give a compiler error unless Foo implements IFoo:

     var builder = new ContainerBuilder();
     builder.Register<IFoo>(c => new Foo()).SingleInstance();

     var container = builder.Build();
     var foo = container.Resolve<IFoo>();

c is the IComponentContext. If the Foo constructor requires a constructor argument then you can write c => new Foo(c.Resolve<IBar>()).

After I have called IoCContainer.Build(..) I can no longer register anything 'into' the BaseContainer

You can update the container in Autofac 2.2.

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