我的应用程序由一个Shell和许多从目录加载的模块组成。我想向每个模块添加Finalize()方法,以便它们可以执行自己所需的清除/关闭代码,例如关闭文件,释放套接字,执行保存/备份等。
我知道可以通过事件聚合和在关闭时发布事件来轻松实现此概念,但是我宁愿遍历每个模块并调用此Finalize()方法,该方法返回一个状态int,该值指示是否遇到了该模块在完成过程中遇到任何问题。
到目前为止,我已经创建了以下简单接口,并使用了适当的模块来实现它。
public interface IFinalizeModule
{
int Finalize();
}
是否可以遍历模块目录中的模块并执行类似的操作而无需创建它们的其他实例?我找到的最接近的东西是在this post中,但我无法理解他的解释
我将每个模块的Start方法放置在一个单独的组件(IStartable)中,使用不同的ID在容器中注册每个组件,并解析/导入IEnumerable以获取所有具有start方法的实例。
此代码不起作用,但这是我要实现的目标
foreach (IModule module in ModuleCatalog)
{
int exitcode = module.Finalize();
if (exitcode != 0)
{
// do something
}
}
答案 0 :(得分:0)
模块是短暂的。它们被创建,初始化和垃圾回收。模块的唯一工作是执行注册。
如果在应用程序关闭时有需要关闭的服务,则在要关闭时必须通知这些服务。通过他们订阅的事件或通过创建RegistryOfServicesThatNeedToBeShutDown
。
示例扩展了我的评论(如果您坚持要在模块级别进行清理):
class MyModule : IModule
{
public void Initialize()
{
_container.RegisterType<IMyService, DisposeMe>( new ContainerControlledLifetimeManager() );
_container.RegisterType<IMyOtherService, DisposeMeToo>( new ContainerControlledLifetimeManager() );
_container.RegisterType<IModuleCleanUp, CleanUpMyModule>( nameof( MyModule ) );
}
private class CleanUpMyModule : IModuleCleanUp
{
void Finalize()
{
_container.Resolve<IMyService>().Dispose();
_container.Resolve<IMyOtherService>().Dispose();
}
}
}
现在,您有一个常规模块及其清理代码彼此相邻。但是代码看起来有点丑陋,有些事情要注意:
IMyService
,那么您就完成了IMyService
的类型是否需要清理:在MyModule
之后初始化的另一个模块可能会为IMyService
注册不同的类型