我有一个Web服务,它将传递一些数据(特别是来自SharePoint文档库的InfoPath xml).我目前正在使用Ninject来处理要加载的数据"策略".这是一些代码(问题如下):
namespace Web.Services
{
public bool AddForm(XmlDocument form, string formName)
{
IKernel kernel = new StandardKernel(new FormsModule());
var ctx = kernel.Get<IPFormDataContext>(formName);
return ctx.DoWork(form);
}
}
Run Code Online (Sandbox Code Playgroud)
namespace Core.Modules
{
public class FormsModule : NinjectModule
{
public override void Load()
{
Bind<IPFormDataContext>().ToSelf().Named("FormA");
Bind<IPFormDataContext>().ToSelf().Named("FormB");
// Snip
Bind<IPFormDataStrategy>().To<FormAStratgey>()
.WhenParentNamed("FormA");
Bind<IPFormDataStrategy>().To<FormBStrategy>()
.WhenParentNamed("FormB");
// Snip
}
}
}
Run Code Online (Sandbox Code Playgroud)
namespace Core.Forms
{
public class IPFormDataContext
{
private IPFormDataStrategy _ipFormDataStrategy;
public IPFormDataContext(IPFormDataStrategy strategy)
{
_ipFormDataStrategy = strategy;
}
public bool DoWork(XmlDocument form)
{
return _ipFormDataStrategy.DoWork(form);
}
}
public abstract class IPFormDataStrategy
{
public abstract bool DoWork(XmlDocument form);
}
}
namespace Core.Forms.FormStrategies
{
class FormAStrategy : IPFormDataStrategy
{
public override bool DoWork(XmlDocument form)
{
// Deserialize form using (xsd.exe generated) FormAData
// and perform some operation on the resulting data.
return resultOfWork;
}
}
}
Run Code Online (Sandbox Code Playgroud)
FormBStrategy和我没有列出的其他7个策略大致相同.我正在尝试找到一种方法将表单xml传递给webservice并根据正在进入的表单类型调用正确的表单反序列化.
上面的代码"有效"; 但感觉我在Ninject做了某种服务,从我正在阅读的内容来看是件坏事.但我想不出一个正确的方法来实现这一目标.我并没有决定使用Ninject或任何IOC/DI框架.
我正在做什么......错了?我可以指出正确的方向吗?
如果您在示例代码中提供的类是准确的(即没有更多的方法和属性)。那么最简单的解决方案可能会起作用,并且您可以摆脱许多类/类的依赖关系。
一个不依赖框架/容器的简单解决方案是:
public static class FormsProcessing
{
private static ConcurrentDictionary<string, Func<FormProcessor>> _registeredProcessors = new ConcurrentDictionary<string, Func<FormProcessor>>();
public delegate bool FormProcessor(XmlDocument form);
public static void RegisterProcessor(string formKey, Func<FormProcessor> formsProcessorFactory)
{
_registeredProcessors.AddOrUpdate(formKey, formsProcessorFactory, (k, current) => formsProcessorFactory);
}
public static FormProcessor GetProcessorFor(string formKey)
{
Func<FormProcessor> processorFactory;
if (_registeredProcessors.TryGetValue(formKey, out processorFactory);
return processorFactory();
return null;
}
public static bool Process(string formKey, XmlDocument form)
{
var processor = GetProcessorFor(formKey);
if (null == processor)
throw new Exception(string.Format("No processor for '{0}' forms available", formKey));
return processor(form);
}
}
Run Code Online (Sandbox Code Playgroud)
用法:
namespace Web.Services
{
public class MyServiceClass
{
public bool AddForm(XmlDocument form, string formName)
{
return FormsProcessing.Process(formName, form);
}
}
}
Run Code Online (Sandbox Code Playgroud)
它简单而明确,不需要或公开对IPFormDataContext
和IPFormDataStrategy
类的某些结构的任何依赖。您拥有的唯一显式依赖项是具有FormProcessor
签名的委托。
与容器类似,您需要在某处执行注册:
FormsProcessing.RegisterProcessor("FormA", () => new FormAStrategy().DoWork);
FormsProcessing.RegisterProcessor("FormB", () => new FormBStrategy().DoWork);
Run Code Online (Sandbox Code Playgroud)
或者,通过扫描程序集的约定(例如接口签名)来添加某种形式的(基于约定的)自动注册也很容易。
归档时间: |
|
查看次数: |
1477 次 |
最近记录: |