如何实现委托工厂?

发布于 2024-08-12 16:15:24 字数 314 浏览 7 评论 0原文

Autofac 的文档有一个有趣的页面,描述了它自动生成 委托工厂。它还强烈建议您可以在没有 Autofac 的情况下通过手写获得类似的结果。

我正在使用 Unity 进行 IoC,并且希望避免将容器传递给需要创建其他对象的对象,那么如何在没有 Autofac 的情况下编写委托工厂呢?

The documentation for Autofac has an interesting page describing its ability to automatically generate delegate factories. It also strongly suggests that you can get similar results without Autofac by writing them by hand.

I'm using Unity for IoC and would like to avoid passing the container around to objects that need to create other objects, so how would you write a delegate factory without Autofac?

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

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

发布评论

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

评论(1

我纯我任性 2024-08-19 16:15:24

嗯,到目前为止我从未使用过 Unity,所以我的答案很模糊。

原理很简单。您定义一些代表工厂的委托。然后,您创建一个“工厂”类,其中具有与委托匹配的公共方法。这个类知道容器。现在您注册委托并将该类设置为实现。然后你可以只注入委托。当您调用注入的委托时,将调用工厂类,它知道容器并向容器请求新实例。

首先,定义工厂代表。

public delegate TServiceType Provider<TServiceType>();
public delegate TServiceType Provider<TArg,TServiceType>(TArg argument);

您创建一个通用工厂:

/// <summary>
/// Represents a <see cref="Provider{TArg,TServiceType}"/> which holds 
/// the container context and resolves the service on the <see cref="Create"/>-call
/// </summary>
internal class GenericFactory{
    private readonly IContainer container; 

    public ClosureActivator(IContainer container)
    {
        this.container= container;
    } 

    /// <summary>
    ///  Represents <see cref="Provider{TServiceType}.Invoke"/>
    /// </summary>
    public TService Create()
    {
        return container.Resolve<TService>();
    }
    /// <summary>
    /// Represents <see cref="Provider{TArg,TServiceType}.Invoke"/>
    /// </summary>
    public TService Create(TArg arg)
    {        
        return container.Resolve<TService>(new[] {new TypedParameter(typeof (TArg),arg)});
    }
}

现在您注册委托,如下所示:

var newServiceCreater = new GenericFactory(container);
container.Register<Provider<MyCompoent>>().To(newServiceCreater.Create);

var newServiceCreater = new GenericFactory(container);
container
    .Register<Provider<OtherServiceWithOneArgumentToConstruct>>()
    .To(newServiceCreater.Create);

现在您只需将“Provider”而不是容器注入到其他组件中。

Well I've never used Unity so far, so my answer is quite vague.

The principal is simple. You define some delegates which represent factories. Then you create a ‘factory’-class which has public methods which matches the delegates. This class knows the container. Now you register the delegate and set that class as implementation. Then you can inject only the delegate. When you call the injected delegate, the factory-class is called, which knows the container and asks the container for a new instance.

First you define your factory-delegates.

public delegate TServiceType Provider<TServiceType>();
public delegate TServiceType Provider<TArg,TServiceType>(TArg argument);

The you create a generic factory:

/// <summary>
/// Represents a <see cref="Provider{TArg,TServiceType}"/> which holds 
/// the container context and resolves the service on the <see cref="Create"/>-call
/// </summary>
internal class GenericFactory{
    private readonly IContainer container; 

    public ClosureActivator(IContainer container)
    {
        this.container= container;
    } 

    /// <summary>
    ///  Represents <see cref="Provider{TServiceType}.Invoke"/>
    /// </summary>
    public TService Create()
    {
        return container.Resolve<TService>();
    }
    /// <summary>
    /// Represents <see cref="Provider{TArg,TServiceType}.Invoke"/>
    /// </summary>
    public TService Create(TArg arg)
    {        
        return container.Resolve<TService>(new[] {new TypedParameter(typeof (TArg),arg)});
    }
}

Now what you register the delegate, something like this:

var newServiceCreater = new GenericFactory(container);
container.Register<Provider<MyCompoent>>().To(newServiceCreater.Create);

var newServiceCreater = new GenericFactory(container);
container
    .Register<Provider<OtherServiceWithOneArgumentToConstruct>>()
    .To(newServiceCreater.Create);

Now other you inject to other components just the ‘Provider’ instead of the container.

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