좋아, 오래 걸릴 수 있습니다. 나는 두 가지 작업을 수행하려고 :포스트 샤프한 양상 주문 실행
내가 모든 통화가 라우팅되는 다른 클래스의 인스턴스를 유지하여 인터페이스를 구현하는 클래스를 갖고 싶어.
또한 모든 메서드 호출을 가로 채고 무언가를하고 싶습니다.
자신의 작품 모두 위대한 작품. 그것들을 결합하는 것은 하나의 실행 명령으로 만 작동하는 것으로 보이며 Murphy가 가지고있는 것처럼, 그것은 잘못된 것입니다 (적어도 저에게는).
나는 모든 전화의 차단이 또한 이전에 주입 된 것을 가로 채기 위해 첫 번째으로 주입하고 싶습니다.
namespace ConsoleApplication13
{
using System;
using System.Reflection;
using PostSharp;
using PostSharp.Aspects;
using PostSharp.Aspects.Dependencies;
using PostSharp.Extensibility;
[Serializable]
[ProvideAspectRole("COMPOSER")]
public sealed class ComposeAspectAttribute : CompositionAspect
{
[NonSerialized]
private readonly Type interfaceType;
private readonly Type implementationType;
public ComposeAspectAttribute(Type interfaceType, Type implementationType)
{
this.interfaceType = interfaceType;
this.implementationType = implementationType;
}
// Invoked at build time. We return the interface we want to implement.
protected override Type[] GetPublicInterfaces(Type targetType)
{
return new[] { this.interfaceType };
}
// Invoked at run time.
public override object CreateImplementationObject(AdviceArgs args)
{
return Activator.CreateInstance(this.implementationType);
}
}
[Serializable]
[ProvideAspectRole("INTERCEPTOR")]
[MulticastAttributeUsage(MulticastTargets.Method)]
[AspectRoleDependency(AspectDependencyAction.Order, AspectDependencyPosition.After, "COMPOSER")]
public sealed class InterceptAspectAttribute : MethodInterceptionAspect
{
public override void CompileTimeInitialize(MethodBase method, AspectInfo aspectInfo)
{
base.CompileTimeInitialize(method, aspectInfo);
// Warning in VS output
Message.Write(method, SeverityType.Warning, "XXX", "Method: " + method.Name);
}
public override void OnInvoke(MethodInterceptionArgs args)
{
Console.WriteLine("Intercepted before");
args.Proceed();
Console.WriteLine("Intercepted after");
}
}
interface ITest
{
void Call();
}
class TestImpl : ITest
{
public void Call()
{
Console.WriteLine("CALL remote implemented");
}
}
[InterceptAspect(AspectPriority = 1)]
[ComposeAspect(typeof(ITest), typeof(TestImpl), AspectPriority = 2)]
class Test
{
// this should, after compilation, have all methods of ITest, implemented through an instance of TestImpl, which get intercepted before TestImpl is called
public void CallLocalImplementedTest()
{
Console.WriteLine("CALL local implemented");
}
}
class Program
{
static void Main()
{
var test = new Test();
ITest t = Post.Cast<Test, ITest>(test);
Console.WriteLine("TEST #1");
t.Call();
Console.WriteLine("TEST #2");
test.CallLocalImplementedTest();
Console.ReadLine();
}
}
}
는 또한 작곡가을 먼저
AspectPriority를 실행하는 작곡가에 의존하는 인터셉터를 만드는
AspectRoleDependency하여 두 가지 측면의 실행 순서에 영향을 시도 먼저 실행하십시오. 테스트로
항상
TEST #1
CALL remote implemented
TEST #2
Intercepted before
CALL local implemented
Intercepted after
가 분명히 작동하지 않습니다를 얻을 수 있습니다. 내 처형 명령이 왜 바뀌지 않았는가? 제가 잘못 했나요? 문서의 세부 사항을 놓쳤습니까? 컴포지션 주입 방식도 가로 채기 위해 무엇을 할 수 있습니까?
당신은 또한 당신의 원하는 결과를 달성하기 위해'TestImpl' 클래스에'InterceptAspect'를 추가해야 . – nemesv
@nemesv 아마도 그렇게해도 TestImpl 클래스는 내 클래스가 아닌 경우가 있습니다.나는 TestImpl을 그대로 둘 수있는 솔루션을 선호한다. – nvoigt
다른 방법으로'ITth' 인터페이스 자체에'[InterceptAspect (AttributeInheritance = MulticastInheritance.Multicast)]를 넣을 수 있습니다. 그러나 이것이 당신이 얻을 수있는 가장 먼 것입니다. 문제는 Postsharp가 일리노이를 한 걸음 씩 흔들며, InterceptAspect를 컴파일 타임에있는 메소드에만 적용하여 새로운 ComposeAspect와 함께 구현 된 인터페이스를 볼 수 없다는 것입니다. 그래서 당신이'ComposeAspect'로 추가하는 타입은 이미'InterceptAspect'에 의해 제공된 로깅 코드를'ITest' 나'TestImpl' 클래스에 넣어야합니다. – nemesv