আমি কীভাবে সি # তে কোনও মেথড কলকে বাধা দেব?


154

প্রদত্ত শ্রেণীর জন্য আমি ট্রেসিং কার্যকারিতা রাখতে চাই অর্থাত আমি প্রতিটি পদ্ধতি কল (পদ্ধতির স্বাক্ষর এবং প্রকৃত প্যারামিটার মান) এবং প্রতিটি পদ্ধতির প্রস্থান (কেবল পদ্ধতি স্বাক্ষর) লগ করতে চাই।

আমি এটি ধরে নিয়ে কীভাবে এটি সম্পাদন করব:

  • আমি সি # এর জন্য কোনও তৃতীয় পক্ষের এওপি লাইব্রেরি ব্যবহার করতে চাই না,
  • আমি যে সমস্ত পদ্ধতিতে ট্রেস করতে চাইছি তাতে আমি নকল কোড যুক্ত করতে চাই না,
  • আমি ক্লাসের পাবলিক এপিআই পরিবর্তন করতে চাই না - শ্রেণীর ব্যবহারকারীদের সমস্ত পদ্ধতিতে একই পদ্ধতিতে কল করতে সক্ষম হওয়া উচিত।

প্রশ্নটি আরও কংক্রিট করার জন্য ধরে নেওয়া যাক এখানে 3 শ্রেণি রয়েছে:

 public class Caller 
 {
     public static void Call() 
     {
         Traced traced = new Traced();
         traced.Method1();
         traced.Method2(); 
     }
 }

 public class Traced 
 {
     public void Method1(String name, Int32 value) { }

     public void Method2(Object object) { }
 }

 public class Logger
 {
     public static void LogStart(MethodInfo method, Object[] parameterValues);

     public static void LogEnd(MethodInfo method);
 }

আমি কিভাবে ডাকা না Logger.LogStart এবং Logger.LogEnd প্রতি কলের জন্য Method1 এবং Method2 পরিবর্তন ছাড়া Caller.Call পদ্ধতি এবং স্পষ্টভাবে কল যোগ ছাড়া Traced.Method1 এবং Traced.Method2 ?

সম্পাদনা: যদি আমাকে কল পদ্ধতিটি কিছুটা পরিবর্তন করার অনুমতি দেওয়া হয় তবে এর সমাধান কী হবে?



1
আপনি যদি জানতে চান যে সি # তে কীভাবে ইন্টারসেপশন কাজ করে তা টিনি ইন্টারসেপ্টরটি একবার দেখুন । এই নমুনাটি কোনও নির্ভরতা ছাড়াই চলে। লক্ষ্য করুন যে আপনি যদি বাস্তব বিশ্বের প্রকল্পগুলিতে এওপি ব্যবহার করতে চান তবে এটি নিজেই প্রয়োগ করার চেষ্টা করবেন না। পোস্টশার্পের মতো লাইব্রেরি ব্যবহার করুন।
জালাল

আমি মেথডেডোরেটর ব্যবহার করে একটি পদ্ধতি কল (আগে এবং পরে) লগিং প্রয়োগ করেছি after দয়া করে github.com/Fody/MododDecorator
দিলহান জয়থিলকে

উত্তর:


69

সি # কোনও এওপি ভিত্তিক ভাষা নয়। এটিতে কিছু এওপি বৈশিষ্ট্য রয়েছে এবং আপনি কিছু অন্যকে অনুকরণ করতে পারেন তবে সি # দিয়ে এওপি তৈরি করা বেদনাদায়ক।

আপনি যা করতে চান ঠিক তা করার উপায়গুলি আমি সন্ধান করেছি এবং এটি করার সহজ কোনও উপায় আমি খুঁজে পাইনি।

যেহেতু আমি এটি বুঝতে পারি, আপনি যা করতে চান এটি এটি:

[Log()]
public void Method1(String name, Int32 value);

এবং এটি করার জন্য আপনার কাছে দুটি প্রধান বিকল্প রয়েছে

  1. মার্শালবাইরফঅবজেক্ট বা কনটেক্সটবাউন্ডঅজেক্ট থেকে আপনার শ্রেণীর বংশগতি অর্জন করুন এবং একটি বৈশিষ্ট্য নির্ধারণ করুন যা ইমেসেজ সিংকের উত্তরাধিকার সূত্রে প্রাপ্ত। এই নিবন্ধ একটি ভাল উদাহরণ আছে। তবুও আপনাকে বিবেচনা করতে হবে যে মার্শালবিআরআইফজেক্ট ব্যবহার করে পারফরম্যান্সটি নরকের মতো নেমে যাবে এবং আমি এটি বোঝাতে চাইছি, আমি একটি 10x পারফরম্যান্স হারিয়েছি যা নিয়ে চেষ্টা করার আগে সাবধানে চিন্তা করুন think

  2. অন্য বিকল্পটি হ'ল সরাসরি ইনজেক্ট করা। রানটাইমের সময়, যার অর্থ আপনাকে প্রতি শ্রেণীর "পড়তে" প্রতিচ্ছবিটি ব্যবহার করতে হবে, এর বৈশিষ্ট্যগুলি পেতে এবং অ্যাপ্রোপিয়েট কলটি ইনজেক্ট করতে হবে (এবং এই বিষয়টির জন্য আমি মনে করি আপনি প্রতিচ্ছবিটি ব্যবহার করতে পারেন না mit এমিট পদ্ধতিটি যেমন আমি মনে করি প্রতিচ্ছবি। ইতিমধ্যে বিদ্যমান পদ্ধতির ভিতরে আপনাকে নতুন কোড প্রবেশের অনুমতি দেবে না)। নকশাকালীন সময়ে এর অর্থ সিএলআর সংকলকটিতে একটি এক্সটেনশন তৈরি করা হবে যা এটি কীভাবে সম্পন্ন হয়েছে সে সম্পর্কে আমার সত্যিই ধারণা নেই।

চূড়ান্ত বিকল্পটি একটি আইওসি ফ্রেমওয়ার্ক ব্যবহার করছে । সম্ভবত এটি নিখুঁত সমাধান নয় কারণ বেশিরভাগ আইওসি ফ্রেমওয়ার্কগুলি এন্ট্রি পয়েন্টগুলি সংজ্ঞায়িত করে যে পদ্ধতিগুলিকে হুক করা যায়, কিন্তু আপনি কী অর্জন করতে চান তার উপর নির্ভর করে এটি একটি যথাযথ অ্যাপ্রোক্সিমেশন হতে পারে।


62
অন্য কথায়, 'আউট'
জন

2
আমার উল্লেখ করা উচিত যে আপনার যদি প্রথম শ্রেণীর ফাংশন থাকে তবে কোনও ফাংশনটি অন্য ভেরিয়েবলের মতোই আচরণ করা যেতে পারে এবং আপনার একটি "মেথড হুক" থাকতে পারে যা তিনি চান does
আরসিআইএক্স

3
তৃতীয় বিকল্পটি হ'ল রানটাইম ব্যবহারের সময় উত্তরাধিকার ভিত্তিক অ্যাওপ প্রক্সি তৈরি করা Reflection.Emit। এই পদ্ধতির Spring.NET দ্বারা নির্বাচিত । তবে, এটির জন্য ভার্চুয়াল পদ্ধতিগুলির প্রয়োজন হবে Tracedএবং কোনও ধরণের আইওসি পাত্রে না ব্যবহারের জন্য সত্যই উপযুক্ত নয়, তাই কেন আমি বুঝতে পারি কেন এই বিকল্পটি আপনার তালিকায় নেই।
মেরিজন

2
আপনার দ্বিতীয় বিকল্পটি হ'ল "আপনার নিজের প্রয়োজন মতো একটি এওপি ফ্রেমওয়ার্কের অংশগুলি লিখুন" যার ফলশ্রুতিতে হবে "ওহ অপেক্ষা কর আমি সম্ভবত নিচে না যাওয়ার পরিবর্তে আমার যে সমস্যাটি সমাধান করেছি তার সমাধান করার জন্য বিশেষভাবে তৈরি একটি তৃতীয় পক্ষের বিকল্পটি ব্যবহার করা উচিত -মোহিত-এখানে-রোড "
রুন এফএস

2
@ জর্জ আপনি নির্ভরতা ইনজেকশন / আইওসি খ্যাতি যেমন এনআইজেক্ট ব্যবহার করে এটি অর্জন করতে কিছু উদাহরণ / লিঙ্ক সরবরাহ করতে পারেন
চরণরাজ গোল্লা

48

এটি অর্জনের সবচেয়ে সহজ উপায় সম্ভবত পোস্টশার্প ব্যবহার করা । এটি আপনার প্রয়োগকৃত বৈশিষ্ট্যের উপর ভিত্তি করে আপনার পদ্ধতির অভ্যন্তরে কোডটি ইনজেক্ট করে। এটি আপনাকে যা চায় ঠিক তা করতে দেয়।

অন্য বিকল্পটি হল পদ্ধতির অভ্যন্তরে কোড ইনজেকশন দেওয়ার জন্য প্রোফাইলিং এপিআই ব্যবহার করা , তবে এটি সত্যই শক্ত।


3
আপনি আইসিওরডিগুগের সাথে স্টাফও ইনজেকশন করতে পারেন তবে এটি দুর্দান্ত মন্দ
স্যাম

9

আপনি যদি একটি ক্লাস লিখেন - এটিকে ট্র্যাকিং বলুন - যা আইডিস্পোজেবল ইন্টারফেসটি কার্যকর করে, আপনি সমস্ত পদ্ধতি বডিটি একটিতে গুটিয়ে রাখতে পারেন

Using( Tracing tracing = new Tracing() ){ ... method body ...}

ট্র্যাকিং ক্লাসে আপনি পদ্ধতিগুলি প্রবেশ করানো এবং প্রস্থানের উপর নজর রাখতে ট্র্যাকিং ক্লাসে যথাক্রমে কন্সট্রাক্টর / ডিসপোজ পদ্ধতিতে ট্রেসগুলির যুক্তি পরিচালনা করতে পারেন। যেমন যে:

    public class Traced 
    {
        public void Method1(String name, Int32 value) {
            using(Tracing tracer = new Tracing()) 
            {
                [... method body ...]
            }
        }

        public void Method2(Object object) { 
            using(Tracing tracer = new Tracing())
            {
                [... method body ...]
            }
        }
    }

প্রচুর প্রচেষ্টার মতো দেখাচ্ছে
লেআরওই

3
প্রশ্নের উত্তর দেওয়ার সাথে এর কোনও যোগসূত্র নেই।
লেটেন্সি

9

আপনি এটি ক্যাসল উইন্ডসর এর মতো একটি ডিআই কনটেইরের ইন্টারসেপশন বৈশিষ্ট্য দিয়ে অর্জন করতে পারেন । প্রকৃতপক্ষে, ধারকটি এমনভাবে কনফিগার করা সম্ভব যে নির্দিষ্ট শ্রেণীর দ্বারা সজ্জিত পদ্ধতিযুক্ত প্রতিটি শ্রেণীর বাধা দেওয়া হবে।

পয়েন্ট # 3 সম্পর্কিত, ওপি এওপি কাঠামো ছাড়াই একটি সমাধান চেয়েছিল। আমি নিম্নলিখিত উত্তরে ধরে নিয়েছি যে বিষয়গুলি এ্যাসপেক্ট, জয়েন্টপয়েন্ট, পয়েন্টকুট ইত্যাদি ছিল এড়ানো উচিত Cast ক্যাসেলওয়াইন্ডসারের ইন্টারসেপশন ডকুমেন্টেশন অনুসারে, তাদের কোনওটিরই জিজ্ঞাসা করা হয় না যে তা সম্পাদন করা প্রয়োজন।

কোনও অ্যাট্রিবিউটরের উপস্থিতির ভিত্তিতে একটি ইন্টারসেপ্টারের জেনেরিক নিবন্ধকরণ কনফিগার করুন:

public class RequireInterception : IContributeComponentModelConstruction
{
    public void ProcessModel(IKernel kernel, ComponentModel model)
    {
        if (HasAMethodDecoratedByLoggingAttribute(model.Implementation))
        {
            model.Interceptors.Add(new InterceptorReference(typeof(ConsoleLoggingInterceptor)));
            model.Interceptors.Add(new InterceptorReference(typeof(NLogInterceptor)));
        }
    }

    private bool HasAMethodDecoratedByLoggingAttribute(Type implementation)
    {
        foreach (var memberInfo in implementation.GetMembers())
        {
            var attribute = memberInfo.GetCustomAttributes(typeof(LogAttribute)).FirstOrDefault() as LogAttribute;
            if (attribute != null)
            {
                return true;
            }
        }

        return false;
    }
}

তৈরি আইকন্ট্রিবিট কম্পোনেন্ট মডেল কনস্ট্রাকশনটিকে ধারকটিতে যুক্ত করুন

container.Kernel.ComponentModelBuilder.AddContributor(new RequireInterception());

এবং আপনি ইন্টারসেপ্টারে নিজে যা খুশি করতে পারেন

public class ConsoleLoggingInterceptor : IInterceptor
{
    public void Intercept(IInvocation invocation)
    {
        Console.Writeline("Log before executing");
        invocation.Proceed();
        Console.Writeline("Log after executing");
    }
}

লগতে আপনার পদ্ধতিতে লগিং বৈশিষ্ট্য যুক্ত করুন

 public class Traced 
 {
     [Log]
     public void Method1(String name, Int32 value) { }

     [Log]
     public void Method2(Object object) { }
 }

নোট করুন যে কোনও শ্রেণীর কিছু পদ্ধতি যদি বাধা দেওয়ার প্রয়োজন হয় তবে অ্যাট্রিবিউটটির কিছু হ্যান্ডলিংয়ের প্রয়োজন হবে। ডিফল্টরূপে, সমস্ত পাবলিক পদ্ধতি বাধা দেওয়া হবে।


5

আপনি যদি সীমাবদ্ধতা ছাড়াই আপনার পদ্ধতিগুলি অনুসরণ করতে চান (কোনও কোড অভিযোজন, কোনও এওপি ফ্রেমওয়ার্ক, কোনও নকল কোড নয়), আমাকে আপনাকে বলি, আপনার কিছু জাদু দরকার ...

সিরিয়াসলি, আমি রানটাইমে এওপি ফ্রেমওয়ার্ক কার্যকর করার জন্য এটি সমাধান করেছি।

আপনি এখানে খুঁজে পেতে পারেন: এনসনসরন। নেট এওপি ফ্রেমওয়ার্ক

আমি এই ধরণের প্রয়োজনের প্রতিক্রিয়া জানাতে এই এওপি ফ্রেমওয়ার্কটি তৈরি করার সিদ্ধান্ত নিয়েছি। এটি খুব সাধারণ ওজনের একটি সাধারণ লাইব্রেরি। আপনি হোম পেজে লগারের উদাহরণ দেখতে পাচ্ছেন।

আপনি যদি কোনও তৃতীয় পক্ষের সমাবেশটি ব্যবহার করতে না চান, আপনি কোড উত্সটি (ওপেন সোর্স) ব্রাউজ করতে পারেন এবং Aspect.Directory.cs এবং Aspect.Directory.Entry.cs উভয় ফাইলই নিজের ইচ্ছানুসারে রূপান্তর করতে পারেন। থিস ক্লাসগুলি রানটাইমে আপনার পদ্ধতিগুলি প্রতিস্থাপন করতে দেয়। আমি শুধু আপনাকে লাইসেন্স সম্মানের জন্য জিজ্ঞাসা করব।

আমি আশা করি আপনার যা প্রয়োজন তা আপনি পেয়ে যাবেন বা অবশেষে একটি এওপি ফ্রেমওয়ার্ক ব্যবহার করতে আপনাকে বোঝাতে পারেন।


4

এটি একবার দেখুন - বেশ ভারী স্টাফ .. http://msdn.microsoft.com/en-us/magazine/cc164165.aspx

এসেনশিয়াল। নেট - ডন বক্সে আপনার যা প্রয়োজন তাকে ইন্টারসেপশন বলে একটি অধ্যায় ছিল। আমি এখানে (ফন্টের রং জন্য দুঃখিত - আমি একটি অন্ধকার থিম ছিল তখন ...) এর কিছু স্ক্র্যাপযুক্ত http://madcoderspeak.blogspot.com/2005/09/essential-interception-using-contexts.html


4

আমি একটি ভিন্ন উপায় খুঁজে পেয়েছি যা আরও সহজ হতে পারে ...

একটি পদ্ধতি ইনভোকমেথড ঘোষণা করুন eth

[WebMethod]
    public object InvokeMethod(string methodName, Dictionary<string, object> methodArguments)
    {
        try
        {
            string lowerMethodName = '_' + methodName.ToLowerInvariant();
            List<object> tempParams = new List<object>();
            foreach (MethodInfo methodInfo in serviceMethods.Where(methodInfo => methodInfo.Name.ToLowerInvariant() == lowerMethodName))
            {
                ParameterInfo[] parameters = methodInfo.GetParameters();
                if (parameters.Length != methodArguments.Count()) continue;
                else foreach (ParameterInfo parameter in parameters)
                    {
                        object argument = null;
                        if (methodArguments.TryGetValue(parameter.Name, out argument))
                        {
                            if (parameter.ParameterType.IsValueType)
                            {
                                System.ComponentModel.TypeConverter tc = System.ComponentModel.TypeDescriptor.GetConverter(parameter.ParameterType);
                                argument = tc.ConvertFrom(argument);

                            }
                            tempParams.Insert(parameter.Position, argument);

                        }
                        else goto ContinueLoop;
                    }

                foreach (object attribute in methodInfo.GetCustomAttributes(true))
                {
                    if (attribute is YourAttributeClass)
                    {
                        RequiresPermissionAttribute attrib = attribute as YourAttributeClass;
                        YourAttributeClass.YourMethod();//Mine throws an ex
                    }
                }

                return methodInfo.Invoke(this, tempParams.ToArray());
            ContinueLoop:
                continue;
            }
            return null;
        }
        catch
        {
            throw;
        }
    }

আমি তারপরে আমার পদ্ধতিগুলি সংজ্ঞায়িত করি

[WebMethod]
    public void BroadcastMessage(string Message)
    {
        //MessageBus.GetInstance().SendAll("<span class='system'>Web Service Broadcast: <b>" + Message + "</b></span>");
        //return;
        InvokeMethod("BroadcastMessage", new Dictionary<string, object>() { {"Message", Message} });
    }

    [RequiresPermission("editUser")]
    void _BroadcastMessage(string Message)
    {
        MessageBus.GetInstance().SendAll("<span class='system'>Web Service Broadcast: <b>" + Message + "</b></span>");
        return;
    }

এখন নির্ভরতা ইনজেকশন ছাড়াই আমি রান সময়ে চেক করতে পারি ...

সাইটে কোনও গেটচাস নেই :)

আশা করি আপনি সম্মত হবেন যে এটি ওজন কম তবে কোনও এওপি ফ্রেমওয়ার্ক বা মার্শালবাইরফঅবজেক্ট থেকে নেওয়া বা রিমোটিং বা প্রক্সি ক্লাস ব্যবহার করে।


4

প্রথমে আপনাকে ইন্টারফেস (মার্শালবাইরফেক্ট সাবজেক্টটি প্রয়োগ করার পরিবর্তে) প্রয়োগ করতে আপনার ক্লাসটি সংশোধন করতে হবে।

interface ITraced {
    void Method1();
    void Method2()
}
class Traced: ITraced { .... }

এরপরে সজ্জিত অবজেক্টে কোনও কলকে বাধা দেওয়ার জন্য যেকোন ইন্টারফেস সাজানোর জন্য আপনাকে রিয়েলপ্রক্সির উপর ভিত্তি করে জেনেরিক মোড়কের বস্তুর প্রয়োজন।

class MethodLogInterceptor: RealProxy
{
     public MethodLogInterceptor(Type interfaceType, object decorated) 
         : base(interfaceType)
     {
          _decorated = decorated;
     }

    public override IMessage Invoke(IMessage msg)
    {
        var methodCall = msg as IMethodCallMessage;
        var methodInfo = methodCall.MethodBase;
        Console.WriteLine("Precall " + methodInfo.Name);
        var result = methodInfo.Invoke(_decorated, methodCall.InArgs);
        Console.WriteLine("Postcall " + methodInfo.Name);

        return new ReturnMessage(result, null, 0,
            methodCall.LogicalCallContext, methodCall);
    }
}

এখন আমরা আইট্রেসডের মেথডড 1 এবং মেথড 2 তে কলগুলি অন্তর্ভুক্ত করতে প্রস্তুত

 public class Caller 
 {
     public static void Call() 
     {
         ITraced traced = (ITraced)new MethodLogInterceptor(typeof(ITraced), new Traced()).GetTransparentProxy();
         traced.Method1();
         traced.Method2(); 
     }
 }

2

আপনি কোডপ্লেক্সে ওপেন সোর্স ফ্রেমওয়ার্ক সিআইজেক্ট ব্যবহার করতে পারেন । আপনি ইনজেক্টর তৈরি করতে ন্যূনতম কোড লিখতে পারেন এবং এটি সিএনজেক্টের সাথে যেকোন কোডকে দ্রুত আটকে রাখতে পারেন। এছাড়াও, যেহেতু এটি ওপেন সোর্স তাই আপনি এটিও প্রসারিত করতে পারেন।

অথবা আপনি এই নিবন্ধে উল্লিখিত পদক্ষেপগুলি অনুসরণ করতে পারেন আইএল ব্যবহার করে ইন্টারসেপ্টিং পদ্ধতি কলগুলি এবং আপনার নিজের ইন্টারসেপ্টর তৈরি করতে পারেন প্রতিবিম্ব ব্যবহার করে C সি # তে ক্লাস করুন।


1

আমি কোনও সমাধান জানি না তবে আমার পদ্ধতি নীচের মত হবে as

শ্রেণিটি (বা এর পদ্ধতিগুলি) একটি কাস্টম বৈশিষ্ট্যের সাথে সাজান। প্রোগ্রামের অন্য কোথাও, একটি সূচনা ফাংশনটি সমস্ত ধরণের প্রতিফলিত হোক, বৈশিষ্ট্যগুলি দিয়ে সজ্জিত পদ্ধতিগুলি পড়ুন এবং পদ্ধতিতে কিছু আইএল কোড ইনজেক্ট করুন। প্রকৃতপক্ষে প্রকৃত পদ্ধতি এবং তারপরে কল করে এমন স্টাব দ্বারা পদ্ধতিটি প্রতিস্থাপন করা আরও বাস্তব হতে পারে । অতিরিক্তভাবে, আমি জানি না আপনি যদি প্রতিবিম্ব ব্যবহার করে পদ্ধতিগুলি পরিবর্তন করতে পারেন তবে পুরো প্রকারটি প্রতিস্থাপন করা আরও ব্যবহারিক হতে পারে।LogStartLogEnd


1

আপনি সম্ভাব্যভাবে জিওএফ ডেকোরেটর প্যাটার্নটি ব্যবহার করতে পারেন, এবং ট্রেসিংয়ের জন্য প্রয়োজনীয় সমস্ত শ্রেণীর 'সাজসজ্জা' করতে পারেন।

আইওসি পাত্রে এটি সম্ভবত সত্যই কার্যকর (তবে আগে নির্দেশক হিসাবে আপনি যদি আইওসি পথের দিকে যেতে যাচ্ছেন তবে পদ্ধতির বিরতি বিবেচনা করতে পারেন)।



1

পরিষ্কার কোড প্রয়োগের জন্য এওপি একটি আবশ্যক, তবে আপনি যদি সি # তে একটি ব্লককে ঘিরে রাখতে চান তবে জেনেরিক পদ্ধতিতে তুলনামূলকভাবে সহজ ব্যবহার রয়েছে। (ইন্টেলি ইন্দ্রিয় এবং দৃ strongly়ভাবে টাইপ কোড সহ) অবশ্যই, এটি এওপির বিকল্প হতে পারে না।

যদিও পোস্টশার্পের সামান্য বগী সমস্যা রয়েছে (আমি উত্পাদনে ব্যবহারের জন্য আত্মবিশ্বাসী বোধ করি না), এটি একটি ভাল জিনিস।

জেনেরিক মোড়কের ক্লাস,

public class Wrapper
{
    public static Exception TryCatch(Action actionToWrap, Action<Exception> exceptionHandler = null)
    {
        Exception retval = null;
        try
        {
            actionToWrap();
        }
        catch (Exception exception)
        {
            retval = exception;
            if (exceptionHandler != null)
            {
                exceptionHandler(retval);
            }
        }
        return retval;
    }

    public static Exception LogOnError(Action actionToWrap, string errorMessage = "", Action<Exception> afterExceptionHandled = null)
    {
        return Wrapper.TryCatch(actionToWrap, (e) =>
        {
            if (afterExceptionHandled != null)
            {
                afterExceptionHandled(e);
            }
        });
    }
}

ব্যবহার এর মতো হতে পারে (অবশ্যই ইন্টেলি অর্থে)

var exception = Wrapper.LogOnError(() =>
{
  MessageBox.Show("test");
  throw new Exception("test");
}, "Hata");

আমি সম্মত হই যে পোস্টশার্প একটি এওপি লাইব্রেরি এবং ইন্টারসেপশন পরিচালনা করবে, তবে আপনার উদাহরণটি সাজানোর কিছুই চিত্রিত করে না। আইওসি কে বাধা দিয়ে বিভ্রান্ত করবেন না। তারা একই নয়।
লেটেন্সি

-1
  1. আপনার নিজের এওপি লাইব্রেরি লিখুন।
  2. আপনার উদাহরণগুলির মধ্যে লগিং প্রক্সি তৈরি করতে প্রতিবিম্বটি ব্যবহার করুন (আপনার বিদ্যমান কোডের কিছু অংশ পরিবর্তন না করে আপনি এটি করতে পারবেন কিনা তা নিশ্চিত নয়)।
  3. সমাবেশটি পুনর্লিখন করুন এবং আপনার লগিং কোডটি ইনজেক্ট করুন (মূলত 1 এর মতো)।
  4. সিএলআরকে হোস্ট করুন এবং এই স্তরে লগিং যুক্ত করুন (আমি মনে করি এটি বাস্তবায়নের সবচেয়ে কঠিন সমাধান, যদিও আপনার সিএলআরতে প্রয়োজনীয় হুক রয়েছে কিনা তা নিশ্চিত নন)।

-3

প্রকাশিত 'নেমফোন' দিয়ে সি # 6 এর আগে আপনি যেটা করতে পারেন তা হ'ল ধীর স্ট্যাকট্রেস এবং লিনাক এক্সপ্রেশন use

যেমন পদ্ধতির জন্য যেমন

    public void MyMethod(int age, string name)
    {
        log.DebugTrace(() => age, () => name);

        //do your stuff
    }

এ জাতীয় লাইন আপনার লগ ফাইলে তৈরি হতে পারে

Method 'MyMethod' parameters age: 20 name: Mike

বাস্তবায়ন এখানে:

    //TODO: replace with 'nameof' in C# 6
    public static void DebugTrace(this ILog log, params Expression<Func<object>>[] args)
    {
        #if DEBUG

        var method = (new StackTrace()).GetFrame(1).GetMethod();

        var parameters = new List<string>();

        foreach(var arg in args)
        {
            MemberExpression memberExpression = null;
            if (arg.Body is MemberExpression)
                memberExpression = (MemberExpression)arg.Body;

            if (arg.Body is UnaryExpression && ((UnaryExpression)arg.Body).Operand is MemberExpression)
                memberExpression = (MemberExpression)((UnaryExpression)arg.Body).Operand;

            parameters.Add(memberExpression == null ? "NA" : memberExpression.Member.Name + ": " + arg.Compile().DynamicInvoke().ToString());
        }

        log.Debug(string.Format("Method '{0}' parameters {1}", method.Name, string.Join(" ", parameters)));

        #endif
    }

এটি তার দ্বিতীয় বুলেট পয়েন্টে সংজ্ঞায়িত প্রয়োজনীয়তা ব্যর্থ করে।
টেড বিঘাম
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.