如何注册在它的构造动态字符串参数在组成根类型? [英] How can I register a type with dynamic string parameters in it's constructor at Composition root?

查看:96
本文介绍了如何注册在它的构造动态字符串参数在组成根类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这些构造函数:

    public Configurator(string workingDirectory, string siteExclusions) : this(directory, exclusions, new ServerManager(), new DirectoryCheck())
    {
    }

    public Configurator(string directory, string exclusions, IServerManager manager, IDirectoryCheck directoryCheck)
    {
        this.manager = manager;
        this.directoryCheck = directoryCheck;
        if (exclusions != null)
        {
            // do stuff
        }

        this.directory = directory;
    }



其中,目录排除通过创建代码创建一个WinForms应用程序中。例如。

Where directory and exclusions are created by the creating code, within a winforms application. E.g.

        using (var configurator = new Configurator(this.CalculatedDirectory(), this.exclusions))
        {
            var output = configurator.ConfigureIIS();
            this.txtOutput.Text = output;
        }



我试图删除第一个构造函数和改造统一DI容器。

I am trying to remove the first constructor and retrofit the Unity DI Container. I have started to make this composition root, to be called from Program:

public static class ApplicationRoot
{
    private static readonly Lazy<IUnityContainer> Container = new Lazy<IUnityContainer>(() =>
    {
        var container = new UnityContainer();
        RegisterTypes(container);
        return container;
    });

    /// <summary>
    /// Gets the configured Unity container.
    /// </summary>
    public static IUnityContainer FetchConfiguredContainer()
    {
        return Container.Value;
    }

    private static void RegisterTypes(IUnityContainer unityContainer)
    {
        unityContainer.RegisterType<IServerManager, ServerManager>();
        unityContainer.RegisterType<IDirectoryCheck, DirectoryCheck>();
    }
}



但我怎么处理字符串目录排除

我知道我可以使用新InjectionConstructor(富)我的作文根,但我不知道该点的值。

I know I can use new InjectionConstructor("foo") in my Composition Root, but I don't know the values at that point.

推荐答案

我问了一个类似的问题,前一阵子 - 的与其他构造与团结参数解析

I asked a similiar question a while ago - Resolve with parameter from other constructor with unity

史蒂芬,以便优雅所说的那样:

As Steven so elegantly put it:

在换句话说,你的[变量名称]参数是运行时数据。注入
运行时数据到组件的初始化期间的组件是
反模式

In other words, your [variable name] parameter is runtime data. Injecting runtime data into components during the components' initialization is an anti-pattern.

我解决它是创建保存值的容器的方法。在我来说,我是能够绑定到WCF的上下文。但它可能是保持一个特定的线程,请求或会话,而不是

The way I solved it was to create a container that hold the value. In my case I was able to bind it to the WCF-context. But it could be hold for a specific thread, request or session instead.

下面是一个例子:

public interface IOperationContext<T>
{
    IDictionary<string, T> Items { get; }
}

public class ThreadOperationContext<T> : IOperationContext<T>
{
    [ThreadStatic]
    private static Dictionary<string, T> _items;

    public IDictionary<string, T> Items
    {
        get
        {
            if (_items == null)
            {
                _items = new Dictionary<string, T>();
            }
            return _items;
        }
    } 
}

public class WcfOperationContext<T> : IExtension<OperationContext>
{
    private readonly IDictionary<string, T> _items;

    private WcfOperationContext()
    {
        _items = new Dictionary<string, T>();
    }

    public IDictionary<string, T> Items
    {
        get { return _items; }
    }

    public static WcfOperationContext<T> Current
    {
        get
        {
            WcfOperationContext<T> context = OperationContext.Current.Extensions.Find<WcfOperationContext<T>>();
            if (context == null)
            {
                context = new WcfOperationContext<T>();
                OperationContext.Current.Extensions.Add(context);
            }
            return context;
        }
    }

    public void Attach(OperationContext owner) { }
    public void Detach(OperationContext owner) { }
}

/// <summary>
/// Provides a collection that will be unique for every operation context.
/// </summary>
/// <typeparam name="T"></typeparam>
public class WcfOperationContextWrapper<T> : IOperationContext<T>
{
    public IDictionary<string, T> Items
    {
        get { return WcfOperationContext<T>.Current.Items; }
    }
}



然后你可以注入 IOperationContext<串GT; 当变量<应该是code>工作目录来进行设置。然后你可以注入它在你需要它,并为您的变量设置实施

Then you can inject an IOperationContext<string> when the variable workingDirectory is supposed to be set. Then you can inject it in the implementation where you need it and have the variable set for you.

例如:

public class MySetter
{
    public MySetter(IOperationContext<string> stringContainer)
    {
        stringContainer["workingDirectory"] = "foo";
    }
}

public class MyGetter
{
    public MyGetter(IOperationContext<string> stringContainer)
    {
        var workingDirectory = stringContainer["workingDirectory"];
    }
}



上面的代码将与WCF和线程独特的工作流程。但是,正如我敢肯定你知道,对于一个特定的线程绑定信息时,一些风险。但我希望它可以引导你在正确的方向。问题的关键是将其绑定到一个容器,使用容器而不是字符串。您可以使用会话而不是 ThreadStatic 如果它的用户特定的等等。

The code above will work with WCF and Thread-unique processes. But, as I'm sure you know, there are several risks when binding information for a specific thread. But I hope it can guide you in the right direction. The point is to bind it to a container and use the container instead of a string. You can use Session instead of ThreadStatic if it's user specific and so on.

这篇关于如何注册在它的构造动态字符串参数在组成根类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆