1

私は、Ninject 依存性注入と、Onion アーキテクチャを使用した 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 アプリケーションにデプロイするだけで済みます。

タイマー ジョブの execute メソッドは、関連する 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.");
            }
        }

これではタイマー ジョブの堅牢性が十分ではなく、ボイラー プレート コードがたくさんあります。私の質問は、このデザインを改善するにはどうすればよいですか? これは最も洗練された方法ではありません。タイマー ジョブの操作コードを抽象化し、タイマー ジョブごとに依存関係を注入する方法を探しています。これが良いアプローチだと思われる場合は、コメントをお聞きしたいと思います。または、誰かがこのような同様の問題に直面した場合はどうなりますか? ありがとう

4

1 に答える 1

0

上記のプレゼンター構築コードで自分の質問に答えたと思います。プロジェクトで依存性注入を使用する場合、注入自体はそれほど重要ではありませんが、コードの記述方法を変更する方法ははるかに重要です。SharePointタイマージョブの操作には、コマンドなどの同様のパターンを使用する必要があります。ブートストラップをより適切に処理したいのですが。

于 2012-07-25T06:59:57.707 に答える