ठीक है, यह लंबा हो सकता है। मैं दो काम करने कोशिश कर रहा हूँ:पोस्टशर्प पहलुओं का निष्पादन निष्पादन
मैं एक वर्ग है कि एक और वर्ग है कि हर कॉल करने के लिए रूट किया जाता है का एक उदाहरण पकड़ कर एक अंतरफलक को लागू करता है करना चाहते हैं।
मैं भी सभी विधि कॉल को रोकना और कुछ करना चाहता हूं।
दोनों अपने कामों पर महान प्रदर्शन करते हैं। उन्हें जोड़ना केवल एक निष्पादन आदेश में काम करता है और जैसा कि मर्फी के पास है, यह गलत है (कम से कम मेरे लिए)।
मैं रचना इंजेक्षन करना चाहते हैं पहले ताकि सभी कॉल के अवरोधन भी उन है कि पहले इंजेक्शन थे रोकना होगा।
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();
}
}
}
मैं
AspectRoleDependency से दो पहलुओं के निष्पादन के आदेश को प्रभावित करने की कोशिश की है, इंटरसेप्टर बनाने पहले
AspectPriority चलाने के लिए संगीतकार पर निर्भर करते हैं, यह भी संगीतकार बनाने पहले भागो
परीक्षण हमेशा की
TEST #1
CALL remote implemented
TEST #2
Intercepted before
CALL local implemented
Intercepted after
यह स्पष्ट रूप से काम नहीं करता है उपज। क्या आपके पास कोई सुराग है कि मेरा निष्पादन आदेश क्यों नहीं बदला है? क्या मैंने कुछ गलत किया, क्या मुझे दस्तावेज़ीकरण में कोई जानकारी याद आई? मैं अपनी रचना-इंजेक्शन विधियों को रोकने के लिए क्या कर सकता हूं?
आप भी अपने वांछित परिणाम प्राप्त करने 'TestImpl' वर्ग पर' InterceptAspect' जोड़ने की जरूरत । – nemesv
@nemesv हालांकि यह संभवतः काम करेगा, TestImpl क्लास कभी-कभी मेरी कक्षा नहीं है।मैं एक समाधान पसंद करूंगा जहां मैं testImpl को छोड़ सकता हूं। – nvoigt
वैकल्पिक रूप से आप 'आईटेस्ट' इंटरफ़ेस पर अपने '[इंटरसेप्टएस्पेक्ट (विशेषता इन्टरिटेंस = मल्टीकास्ट इन्हेरिटेंस। मल्टीकास्ट)] डाल सकते हैं। लेकिन यह सबसे दूर है कि आप क्या प्राप्त कर सकते हैं। समस्या यह है कि पोस्टशर्प आईएल को एक चरण में लहराता है और यह केवल 'इंटरसेप्टएस्पेक्ट' को लागू करता है जो संकलन समय पर मौजूद हैं, इसलिए इसे 'कंपोज़एस्पेक्ट' के साथ जोड़े गए नए इंटरफ़ेस कार्यान्वयन को नहीं देखा जाता है। तो जिस प्रकार आप 'कंपोज़एस्पेक्ट' के साथ जोड़ते हैं, उसमें 'इंटरसेप्टएस्पेक्ट' द्वारा प्रदान किए गए लॉगिंग कोड में पहले से ही 'आईटेस्ट' या 'टेस्टआईएमपीएल' वर्ग पर डालने के साथ होना चाहिए। – nemesv