M.B*_*ock 9 c# singleton inversion-of-control
关于单身人士的使用,似乎有一种耻辱.我从来没有亲自接受它,但为了开放的思想,我试图尝试将IoC概念作为替代方案,因为我坦率地厌倦了我的日常工作,并希望尝试不同的东西.如果我对IoC概念的解释不正确或误导,请原谅我.
下面是这样的情况:我正在HttpListenerWindows服务中构建一个基于简单的Web服务器,它利用插件模型来确定如何根据请求的URL处理请求(就像其他人询问的那样HttpListener).我发现插件的方法是查询配置目录以查找用a装饰的程序集HttpModuleAssemblyAttribute.这些程序集可以包含0个或更多IHttpModule子项,这些子项另外HttpModuleAttribute用于指定模块的名称,版本,人类可读描述和各种其他信息.就像是:
[HttpModule(/*Some property values that matter */)]
public class SimpleHttpModule : IHttpModule
{
public void Execute(HttpListenerContext context)
{
/* Do Something Special */
}
}
Run Code Online (Sandbox Code Playgroud)
当HttpModule发现a时,我通常会将它添加到一个Dictionary<string, Type>对象中,该对象的唯一目的是跟踪我们所知道的模块.这本词典通常会出现在我的各种单身人士中,这种单身人士具有ACE风格的单身人士(我从C++那里学习单身人士的遗产).
现在我想要实现的是使用(我的理解)一般IoC概念类似的东西.基本上我所拥有的是一个AppService集合,IAppService其定义为:
public interface IAppService : IDisposable
{
void Initialize();
}
Run Code Online (Sandbox Code Playgroud)
我的插件AppService看起来像:
[AppService("Plugins")]
internal class PluginAppService : IAppService, IDictionary<string, Type>
{
/* Common IDictionary Implementation consisting of something like: */
internal Type Item(string modName)
{
Type modType;
if (!this.TryGetValue(modName, out modType)
return null;
return modType;
}
internal void Initialize()
{
// Find internal and external plug-ins and add them to myself
}
// IDisposable clean up method that attempts to dispose all known plug-ins
}
Run Code Online (Sandbox Code Playgroud)
然后在服务期间,OnStart我实例化一个AppServices本地已知的实例,但是传递给所有实例化插件的构造函数:
public class AppServices : IDisposable, IDictionary<string, IAppService>
{
/* Simple implementation of IDictionary */
public void Initialization()
{
// Find internal IAppService implementations, instantiate them (passing this as a constructor parameter), initialize them and add them to this.
// Somewhere in there would be something like
Add(appSvcName, appSvc);
}
}
Run Code Online (Sandbox Code Playgroud)
我们曾经的单一方法实现成为一个抽象实现+子上的构造函数:
[HttpModule(/*Some property values that matter */)]
public abstract class HttpModule : IHttpModule
{
protected AppServices appServices = null;
public HttpModule(AppServices services)
{
appServices = services;
}
public abstract void Execute(HttpListenerContext context);
}
[HttpModule(/*Some property values that matter */)]
public class SimpleHttpModule : HttpModule
{
public SimpleHttpModule(AppServices services) : base(services) { }
public override void Execute(HttpListenerContext context)
{
/* Do Something Special */
}
}
Run Code Online (Sandbox Code Playgroud)
对常用应用程序服务的任何访问都变为:
var plugType = appServices["Plugins"][plugName];
Run Code Online (Sandbox Code Playgroud)
而不是:
var plugType = PluginManager.Instance[plugName];
Run Code Online (Sandbox Code Playgroud)
我是否遗漏了一些基本的IoC概念,这将简化这一切,或者是否真的有益于所有这些额外的代码?在我的世界中,单身人士是一种简单的生物,它允许整个程序中的代码访问所需的(相对静态的)信息(在这种情况下是类型).
更明确地提出问题:
虽然我仍然不太相信 IoC/DI在这种情况下更好,但随着项目范围的扩大,我确实看到了好处。对于日志记录和可配置性之类的事情来说,这无疑是正确的方法。
我期待在未来的项目中更多地尝试它。
| 归档时间: |
|
| 查看次数: |
1567 次 |
| 最近记录: |