Ok, điều này có thể kéo dài. Tôi đang cố gắng làm hai việc:Sắp xếp các thực thi Các khía cạnh của Postsharp
Tôi muốn có một lớp thực hiện giao diện bằng cách giữ một thể hiện của một lớp khác mà mọi cuộc gọi được định tuyến đến.
Tôi cũng muốn chặn tất cả các cuộc gọi phương thức và làm điều gì đó.
Làm cả hai đều hoạt động tốt. Kết hợp chúng dường như chỉ hoạt động trong một trật tự thực hiện và khi Murphy có nó, đó là sai lầm (ít nhất là đối với tôi).
Tôi muốn tiêm thành phần trước tiên để chặn tất cả các cuộc gọi cũng sẽ chặn những người đã được tiêm trước đó.
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();
}
}
}
tôi đã cố gắng gây ảnh hưởng đến trật tự thực hiện hai khía cạnh của
AspectRoleDependency, làm cho đánh chặn phụ thuộc vào nhà soạn nhạc để chạy đầu tiên
AspectPriority, cũng làm cho nhà soạn nhạc chạy trước.
Khi kiểm tra luôn mang lại
TEST #1
CALL remote implemented
TEST #2
Intercepted before
CALL local implemented
Intercepted after
nó rõ ràng không hoạt động. Bạn có một đầu mối tại sao lệnh thực hiện của tôi không thay đổi? Tôi đã làm điều gì đó sai, tôi đã bỏ lỡ một chi tiết trong tài liệu? Tôi có thể làm gì để ngăn chặn các phương pháp tiêm thành phần của tôi?
Bạn cũng cần phải thêm 'InterceptAspect' trên lớp 'TestImpl' để đạt được kết quả mong muốn của bạn . – nemesv
@nemesv Mặc dù điều đó có thể làm việc, nhưng lớp TestImpl không phải là lớp của tôi đôi khi.Tôi muốn một giải pháp mà tôi có thể để lại TestImpl như nó được. – nvoigt
Ngoài ra, bạn có thể đặt '[InterceptAspect (AttributeInheritance = MulticastInheritance.Multicast)]' trên chính giao diện 'ITest'. Nhưng đây là điều xa nhất bạn có thể nhận được. Vấn đề là Postsharp làm IL vẫy trong một bước và nó chỉ áp dụng 'InterceptAspect' cho các phương thức có mặt tại thời gian biên dịch để nó không thấy các triển khai giao diện mới được thêm vào với' ComposeAspect'. Vì vậy, kiểu bạn thêm vào với 'ComposeAspect' phải chứa mã đăng nhập được cung cấp bởi' InterceptAspect' với việc đặt nó vào 'ITest' hoặc trên lớp' TestImpl'. – nemesv