4

数か月前、私は PostSharp を発見しました。

しかしその後、リーガルは古いバージョンのライセンスが気に入らないという回答を返してきました。その後、部門は 2.0 の価格が (必要な座席数に対して) 受け入れがたいほど高いことを教えてくれました. そのようなフレームワークはこれだけではありえない、と私は思いました。

私は代替品を探し続けましたが、そのほとんどは死んでいるか、メンテナンスが不十分で (特にドキュメンテーション部門で)、学術的な使用のために、または上記のすべてでした (私はあなたの Aspect.Net を見ています)。

その後、Spring.Net を発見しました。しばらくの間、それは良かったです。

私はドキュメンテーションを読んでいて、AOP 涅槃の優れた絵のように見えるものを描き続けました。コード インターセプトを行う場所をマークするために属性にロックされることはなくなりましたが、XML で構成することができ、それを変更しても再コンパイルする必要はありませんでした。偉大な。

次に、サンプルを調べたところ、すべての使用シナリオで次のことがわかりました。

// Create AOP proxy using Spring.NET IoC container.
IApplicationContext ctx = ContextRegistry.GetContext();
ICommand command = (ICommand)ctx["myServiceCommand"];    
command.Execute();
if (command.IsUndoCapable)
{
    command.UnExecute();
}

コードの最初の 2 行が存在しなければならないのはなぜですか? それはすべてを台無しにします。これは、適切なメソッド/クラス/などに適切な属性を貼り付けたり、XML で一致パターンを編集したりすることによって、ユーザーが使用できるアスペクトと属性のセットまたは XML 構成を単純に提供することはできないことを意味します。これを機能させるには、プログラム ロジックを変更する必要があります。

この場合、Spring.Net を PostSharp として動作させる方法はありますか? (つまり、ユーザーは属性/XML 構成を追加するだけでよく、メソッドのコンテンツを編集する必要はありません。

または、PostSharp に代わる価値のある機能的な代替手段はありますか? SO でこのようなタイトルの質問をいくつか見たことがありますが、実際に PostSharp を置き換えようとしている人はいませんでした。その機能を補完したかっただけです。フル交換が必要です。

4

2 に答える 2

9

要するに、はい、Spring.Net AOP は、XML ベースの構成を使用して記述した方法で機能します。これらの最初の 2 行のコードを使用する必要はありません。実際、コードベースの構成は推奨されません。XML ベースの構成のみを使用して Spring.Net AOP を構成できますが、これは実際に推奨されるアプローチです。

これにはいくつかの手順があります。

  1. アドバイスを作成します。BeforeAdvice、AroundAdvice、AfterReturningAdvice、および ThrowsAdvice は、サポートされているアドバイスのタイプです。AroundAdvice は AOPAlliance インターフェースを使用し、その他は Spring.AOP インターフェースを使用します。
  2. ポイントカットを定義する
  3. ポイントカットとアドバイスを適用する

構成例 (ライブ構成から一般化):

  <!-- START Spring.Net AOP -->

  <object id="beforeAdvice" type="MyBeforeAdvice, MyAOP"></object>
  <object id="beforeAdvisor" type="Spring.Aop.Support.DefaultPointcutAdvisor, Spring.Aop">
    <property name="Advice" ref="beforeAdvice" />
  </object>

  <object id="returnsAdvice" type="MyAfterReturningAdvice, MyAOP"></object>
  <object id="returnsAdvisor" type="Spring.Aop.Support.DefaultPointcutAdvisor, Spring.Aop">
     <property name="Advice" ref="returnsAdvice" />
  </object>

  <object id="throwsAdvice" type="MyThrowsAdvice, MyAOP"></object>
  <object id="throwsAdvisor" type="Spring.Aop.Support.DefaultPointcutAdvisor, Spring.Aop">
    <property name="Advice" ref="throwsAdvice" />
  </object>


  <!-- Advise objects -->
  <object type="Spring.Aop.Framework.AutoProxy.ObjectNameAutoProxyCreator, Spring.Aop">
    <property name="ObjectNames">
      <list>
        <value>*Command</value>
        <value>...</value>
      </list>
    </property>
    <property name="InterceptorNames">
      <list>
        <value>beforeAdvisor</value>
        <value>returnsAdvisor</value>
        <value>throwsAdvisor</value>
      </list>
    </property>
  </object> 


  <!-- END Spring.Net AOP -->

ウィービングは実行時に実行され、非常に高速で邪魔になりません。

これが役に立つことを願って、

アンドリュー

于 2010-03-25T16:10:50.650 に答える
2

ルックアップメソッドのインジェクション機能を探していると思います。

Spring.NETアプリケーションコンテキストを最初のどこかにロードしました。Spring.NETへのコードベースの依存関係は最小限です。問題は、(アドバイスされた)サービスが必要なすべての場所で、ContextRegistry.GetContext()を使用してSpring.NETに明示的に依存していることです。

ルックアップメソッドを使用したメソッド置換でこれを回避できます。例:

AbstractCommandFactoryを作成します。

namespace MyNamespace {
  public abstract class AbstractCommandFactory : ICommandFactory {
    public abstract ICommand getMyCommand();  
  }
}

Spring.NETを使用すると、getMyCommandがSpring.NETオブジェクトを返すことができます

<objects>
  <object id="commandfactory"
          type="MyNamespace.AbstractCommandFactory, MyAssembly">
    <lookup-method name="getMyCommand" object="commands.mycommand" />
  </object>

  <object id="commands.mycommand" 
          type=MyNamespace.MyCommandImplementation, MyAssembly" />
</objects>

ここで、Spring.NETアプリケーションコンテキストを初期化するときに、このコマンドファクトリをロードし、参照を渡します。MyCommandImplementationのインスタンスが必要な場合は、ファクトリインスタンスからインスタンスをリクエストするだけです。

public void doSomeWork() {
  // factory is an ICommandFactory
  // instantiated earlier using the explicit context.getObject("commandfactory")
  ICommand myCommand = this.factory.getMyCommand();
  myCommand.Execute();
}

これで、Spring.NETへの明示的な依存関係はごくわずかになります。つまり、初期ロード+ファクトリのインスタンス化時のみです。コードの残りの部分はクリーンなままです。

ボーナスポイント:ICommandFactory / ICommandモックをより簡単に作成して、コードの単体テストを行うことができます。

于 2010-11-05T11:17:42.717 に答える