0

こんにちは、このようなファクトリコードがあります。辞書に直接保存する代わりに、これらの値をapp.configファイルに保存したいと思います。私が以下に示したように。

public class HandlerFactory
    {
        private Dictionary<string, IHandler> _handlers = new Dictionary<string,IHandler>();
        public HandlerFactory()
        {
            _handlers.Add("AMOUNT", new AmountValidator());
            _handlers.Add("FLOW", new FlowValidator());
        }
        public IHandler Create(string key)
        {
            IHandler result;
            _handlers.TryGetValue(key, out result);
            return result;
        }
    }

以下に示すように、これらの設定を構成ファイルに移動します。

  <?xml version="1.0" encoding="utf-8" ?>
        <configuration>
        <configSections>
            <section name="Indentifiers" type="System.Configuration.AppSettingsSection"/>
        </configSections>
        <Indentifiers>
            <add key="AMOUNT" value="AmountValidator" />
            <add key="FLOW" value="FlowValidator" />
        </Indentifiers>
    </configuration>

私はこのようなことをしていましたが、成功しませんでした。辞書に追加する方法がわからない

NameValueCollection settings = ConfigurationManager.GetSection("Indentifiers") as NameValueCollection;
                if (settings != null)
                {
                    foreach (string key in settings.AllKeys)
                    {
                        _handlers.Add(key.ToString(), settings[key].ToString()); <-- how to handle here
                    }
                 }
4

2 に答える 2

0
public interface IHandler
{
    void Handle();
}

public sealed class HandlerFactory
{
    private readonly Dictionary<string, Type> _map = new Dictionary<string, Type>();

    public HandlerFactory()
    {
        var handlers = (NameValueCollection)ConfigurationManager.GetSection("Handlers");
        if (handlers == null)
            throw new ConfigurationException("Handlers section was not found.");
        foreach (var key in handlers.AllKeys)
        {
            var typeName = handlers[key] ?? string.Empty;
            // the type name must be qualified enough to be 
            // found in the current context.
            var type = Type.GetType(typeName, false, true);
            if (type == null)
                throw new ConfigurationException("The type '" + typeName + "' could not be found.");
            if (!typeof(IHandler).IsAssignableFrom(type))
                throw new ConfigurationException("The type '" + typeName + "' does not implement IHandler.");
            _map.Add(key.Trim().ToLower(), type);
        }
    }

    // Allowing your factory to construct the value 
    // means you don't have to write construction code in a million places.
    // Your current implementation is a glorified dictionary
    public IHandler Create(string key)
    {
        key = (key ?? string.Empty).Trim().ToLower();
        if (key.Length == 0)
            throw new ArgumentException("Cannot be null or empty or white space.", "key");
        Type type;
        if (!_map.TryGetValue(key, out type))
            throw new ArgumentException("No IHandler type maps to '" + key + "'.", "key");
        return (IHandler)Activator.CreateInstance(type);
    }
}
于 2012-07-28T06:50:52.327 に答える
0

ChaosPandion が指摘しているように、CreateInstance メソッドが役立つはずです。両方のハンドラー タイプが IHandler を実装し、それらが実行中のアセンブリに配置されていると仮定すると、

_handler.Add(key.ToString(), Activator.CreateInstance(null, settings[key].ToString()));

トリックを行う必要があります! http://msdn.microsoft.com/en-us/library/d133hta4.aspx 最初の引数はアセンブリの名前で、null のデフォルトは実行中のアセンブリです。

于 2012-07-27T19:20:26.747 に答える