我使用Onion架构成功实现了使用Ninject依赖注入和其他基础架构(如NLog日志记录等)的企业SharePoint解决方案。使用HttpModule作为注入框架的组合根,它非常适合普通的Web请求:
public class SharePointNinjectHttpModule: IHttpModule, IDisposable
{
private readonly HttpApplication _httpApplication;
public void Init(HttpApplication context)
{
if (context == null) throw new ArgumentException("context");
Ioc.Container = IocContainerFactory.CreateContainer();
}
public void Dispose()
{
if(_httpApplication == null) return;
_httpApplication.Dispose();
Ioc.Container.Dispose();
}
}
CreateContainer方法从单独的类库加载Ninject模块,并抽象出我的ioc容器。 对于普通的Web应用程序请求,我使用了一个名为Ioc的注入器的共享静态类。 UI层具有MVP模式实现。例如,在aspx页面中,演示者的构造如下:
presenter = Ioc.Container.Get<SPPresenter>(new Ninject.Parameters.ConstructorArgument("view", this));
我仍然依赖于参数的Ninject参考。有没有办法抽象这个,除了在界面中映射很多方法?我不能只为参数传递简单类型吗?
注入本身效果很好,但是在使用外部进程(如SharePoint计时器作业)时遇到了困难。从这里重用ioc容器显然是一个可怕的想法,因此它需要自己引导依赖项。此外,它需要从Web应用程序池加载配置,而不是管理Web应用程序。否则,该作业只能在应用程序服务器上运行。这样,作业可以在任何Web服务器上运行,并且您的SharePoint功能只需要将配置等部署到Web应用程序。
这是我的计时器作业的执行方法,它打开关联的Web应用程序配置并将其传递给日志记录服务(nlog)并从外部Web配置服务读取它的配置。我编写的代码读取配置文件中的自定义部分并初始化NLog日志记录基础结构。
public override void Execute(Guid contentDbId)
{
try
{
using (var ioc = IocContainerFactory.CreateContainer())
{
// open configuration from web application
var configService = ioc.Get<IConfigService>(new ConstructorArgument("webApplicationName", this.WebApplication.Name));
// get logging service and set with web application configuration
var logginService = ioc.Get<ILoggingService>();
logginService.SetConfiguration(configService);
// reapply bindings
ioc.Rebind<IConfigService>().ToConstant(configService);
ioc.Rebind<ILoggingService>().ToConstant(logginService);
try
{
logginService.Info("Test Job started.");
// use services etc...
var productService = ioc.Get<IProductService>();
var products = productService.GetProducts(5);
logginService.Info("Got products: " + products.Count() + " Config from web application: " + configService.TestConfigSetting);
logginService.Info("Test Job completed.");
}
catch (Exception exception)
{
logginService.Error(exception);
}
}
}
catch (Exception exception)
{
EventLog.WriteError(exception, "Exception thrown in Test Job.");
}
}
这不会使定时器作业足够稳健,并且有很多锅炉板代码。我的问题是如何改进这种设计?它不是最优雅的,我正在寻找一种方法来抽象计时器作业操作代码,并为每个计时器作业注入它的依赖关系。如果您认为这是一个好方法,我想听听您的意见。或者,如果有人遇到过类似的问题?感谢
答案 0 :(得分:0)
我想我已经用上面的演示者构造代码回答了我自己的问题。在项目中使用依赖项注入时,注入本身并不重要,但它改变编写代码的方式更为重要。我需要使用类似的模式,例如我的SharePoint计时器作业操作的命令。我只是想更好地处理自举。