2012-07-21 60 views
1

我已成功实施企业SharePoint解决方案,使用Ninject依赖注入和其他基础结构(如NLog日志记录等使用洋葱式体系结构)。随着HTTP模块作为组成为根的注入框架,它正常的Web请求的伟大工程:SharePoint定时器作业中的Ninject依赖项注入

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应用程序中即可。

这里是我的计时器作业的执行方法,它会打开相关的网页应用程序的配置,并把它传递给日志服务(n日志),并读取它从外部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

我想我已经回答了我自己上面的演示施工规范的问题。在项目中使用依赖注入时,注入本身并不重要,但它改变代码编写方式的方式更为重要。我需要为我的SharePoint计时器作业操作使用类似的模式,例如命令。我只想让bootstrapping得到更好的处理。