C# 抽象工厂从配置添加到字典
嗨,我的工厂代码是这样的。我希望将这些值存储在app.config文件中,而不是直接存储在字典中。正如我在下面所展示的C# 抽象工厂从配置添加到字典,c#,configuration,dictionary,abstract-factory,C#,Configuration,Dictionary,Abstract Factory,嗨,我的工厂代码是这样的。我希望将这些值存储在app.config文件中,而不是直接存储在字典中。正如我在下面所展示的 public class HandlerFactory { private Dictionary<string, IHandler> _handlers = new Dictionary<string,IHandler>(); public HandlerFactory() {
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>
公共类HandlerFactory
{
私有字典_handlers=新字典();
公共手工业厂()
{
_Add(“AMOUNT”,newamountvalidator());
_Add(“FLOW”,newflowvalidator());
}
公共IHandler创建(字符串键)
{
IHandler结果;
_TryGetValue(键,输出结果);
返回结果;
}
}
我想将这些设置移动到我的配置文件中,如下所示
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
}
}
NameValueCollection settings=ConfigurationManager.GetSection(“标识符”)作为NameValueCollection;
如果(设置!=null)
{
foreach(设置中的字符串键。所有键)
{
_handlers.Add(key.ToString(),settings[key].ToString());正如Chaosption所指出的,CreateInstance方法应该很有用。
假设这两种处理程序类型都实现IHandler,并且它们位于正在运行的程序集中
_handler.Add(key.ToString(), Activator.CreateInstance(null, settings[key].ToString()));
你应该做这个把戏!
第一个参数是程序集的名称,null默认为正在执行的程序集。公共接口IHandler
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);
}
}
{
无效句柄();
}
公共密封类手具厂
{
专用只读词典_map=new Dictionary();
公共手工业厂()
{
var handlers=(NameValueCollection)ConfigurationManager.GetSection(“handlers”);
if(handlers==null)
抛出新的ConfigurationException(“未找到处理程序节”);
foreach(处理程序中的var key.allkey)
{
var typeName=handlers[key]??string.Empty;
//类型名称必须足够限定,才能
//在当前上下文中找到。
var type=type.GetType(typeName,false,true);
if(type==null)
抛出新的ConfigurationException(“找不到类型“”+typeName+”);
如果(!typeof(IHandler).IsAssignableFrom(type))
抛出新的ConfigurationException(“类型''+typeName+“'未实现IHandler”);
_map.Add(key.Trim().ToLower(),type);
}
}
//允许您的工厂构建价值
//这意味着您不必在一百万个地方编写构造代码。
//您当前的实现是一个美化的字典
公共IHandler创建(字符串键)
{
key=(key??string.Empty).Trim().ToLower();
如果(key.Length==0)
抛出新ArgumentException(“不能为null、空或空白。”、“键”);
类型;
if(!\u映射TryGetValue(键,输出类型))
抛出新的ArgumentException(“没有IHandler类型映射到“+key+”。”,“key”);
return(IHandler)Activator.CreateInstance(类型);
}
}
Activator.CreateInstance
在这里应该很有用。您好,我在我的主类中调用CreateInstance,而不是在工厂类中。在我的主类中,我正在执行类似于“IHandler validator=handle.Create(arInfo[0].ToString();IHandler handler=(IHandler)Activator.CreateInstance”的操作(“验证”,validator.ToString()).Unwrap()但我不明白如何将key的值转换为IHandler类型。例如,在我的工厂类中,从'AmountValidator'转换为'AmountValidator of type IHandler'。你明白我的意思了吗?你能告诉我吗?我想你不明白工厂的目的。想一想定义。汽车工厂会生产c的蓝图吗ar还是实际的汽车?嗨,olagjo,我不想在我的factory类上创建实例,而是在我的主类中创建。如图所示'HandlerFactorys handle=new HandlerFactorys();if(handle.isValid(arInfo[0].ToString()){IHandler validator=handle.create(arInfo[0].ToString());IHandler handler=(IHandler)Activator.CreateInstance(“验证”,validator.ToString()).Unwrap();handler.Validate(Message);}“但问题是,当我从配置读取时,如何将字符串转换为类型Ihandler?你明白我的问题了吗?多亏了混沌,我在“类型”验证时出错。BuyValidator”没有实现Ihandler,即使它实现了Ihandler。“我的配置文件类似于@bayyinah-如果仔细查看我的原始代码,你会注意到。”检查类型是否实现IHandler的if语句需要被否定。