0

プロパティが使用されるとすぐに、特定のクラスのインスタンスを常に傍受する方法を探しています..

たとえば、MyTestClass が傍受される場合、これにより傍受がトリガーされます。

var myObj = new MyTestClass();
var x = myObj.SomeProperty;

それはメソッド「get_SomeProperty」をインターセプトします..しかし、Unityを使用して見たすべての例では、container.Resolve();を介してMyTestClassのインスタンスの作成を「パイプ」する必要があります..それを避けたい. . それは可能ですか?.. 以前に Castle.DynamicProxy を使用してこのようなことをしたことがあると確信しています.. しかし、私の現在のアプリケーションにはたまたま Unity がインストールされていたので、可能な限り Unity を再利用するのは良い考えのように思えました。可能。

container.Resolve() を使用しないもう 1 つの理由は、私のこのインスタンスが、コンテナーへの論理参照を持たない MVC アクション内で作成される可能性があることです。コンストラクタは非常に良いアイデアです..

ブラ、インクス

4

3 に答える 3

2

よし、これで…

まず、次のドメイン クラス定義があるとします。

public interface IInterceptableClass
{
    string FirstName { get; set; }
    string LastName { get; }
    string GetLastName();
}

public class InterceptableClass : IInterceptableClass
{
    public string FirstName { get; set; }
    public string LastName { get; private set; }

    public InterceptableClass()
    {
        LastName = "lastname";
    }

    public string GetLastName()
    {
        return LastName;
    }
}

そして、次のように定義された単純なインターセプターの動作があるとします。

internal class SampleInterceptorBehavior : IInterceptionBehavior
{
    public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
    {
        // this invokes the method at the tip of the method chain 
        var result = getNext()(input, getNext);

        // method executed with no exceptions (yay)
        if (result.Exception == null)
        {
            //input.Target
            Console.WriteLine($"intercepting: target={input.Target.ToString()}, method={input.MethodBase.Name}");
        }
        else // boo..!
        {
            // handle exception here
            Console.WriteLine($"error! message={result.Exception?.Message}");
        }

        return result;
    }

    public IEnumerable<Type> GetRequiredInterfaces()
    {
        return Type.EmptyTypes;
    }

    public bool WillExecute { get { return true; } }
}

Unity次のように配線します。

    static void Main(string[] args)
    {
        var container = new UnityContainer();
        container.AddNewExtension<Interception>();
        container.RegisterType<IInterceptableClass, InterceptableClass>(
            new Interceptor<TransparentProxyInterceptor>(),
            new InterceptionBehavior<SampleInterceptorBehavior>());

        var myInstance = container.Resolve<IInterceptableClass>();

        // just want to illustrate that privae sets are not supported...
        myInstance.FirstName = "firstname";
        var lastname = myInstance.GetLastName();

        Console.ReadLine();
    } 

Unity を使用して傍受を接続しない場合は、これを手動で行う必要があることに注意してください。1回限りの場合、一部の開発者はその方法を好むかもしれませんが、実際には、その道は持続不可能であり、複数の傍受があり、非常に残忍であることが常にわかりました. そのため、可能であれば常に Unity を使用してください。

ただし、どうしても Unity をバイパスする必要がある場合は、次のようにします。

        var manualInstance = Intercept.ThroughProxy<IInterceptableClass>(
            new InterceptableClass(), // <-- this could be an already-existing instance as well...
            new TransparentProxyInterceptor(), 
            new IInterceptionBehavior[]
            {
                new SampleInterceptorBehavior()
            });

        manualInstance.FirstName = "firstname";
        var lastname = manualInstance.GetLastName();
于 2015-10-02T14:34:24.497 に答える
0

ドキュメントから:

Intercept クラスを使用すると、Unity インターセプトを依存性注入コンテナーのないスタンドアロン機能として使用できます。

ただし、構文は醜いです。

于 2015-10-02T12:59:19.360 に答える