আমি কি লাইব্রেরির জন্য ILogger, ILogger <T>, ILoggerFactory বা ILoggerProvider নিতে পারি?


113

এটি কিছুটা পাস আইলগার বা আইলগারফ্যাক্টির সাথে অ্যাস্পনেট কোরের নির্মাণকারীর সাথে সম্পর্কিত হতে পারে ? তবে এটি বিশেষত গ্রন্থাগার নকশা সম্পর্কে , সেই লাইব্রেরিগুলি ব্যবহার করে এমন প্রকৃত প্রয়োগ কীভাবে এটির লগিং কার্যকর করে তা নয়।

আমি একটি .net স্ট্যান্ডার্ড 2.0 লাইব্রেরী যে Nuget মাধ্যমে ইনস্টল করা হবে লিখছি, এবং যে লাইব্রেরী কিছু ডিবাগ তথ্য পেতে ব্যবহার সম্প্রদায়! আমি তার উপর নির্ভর করে আছি করার অনুমতি Microsoft.Extensions.Logging.Abstractions একটি প্রমিত লগার ইনজেকশনের করার অনুমতি।

যাইহোক, আমি একাধিক ইন্টারফেস এবং ওয়েবে নমুনা কোডটি মাঝে মাঝে ILoggerFactoryশ্রেণীর কর্টারে লগার ব্যবহার এবং তৈরি করি। এর রয়েছে ILoggerProviderযা কারখানার একটি শুধুমাত্র-পঠনযোগ্য সংস্করণ মত দেখায়, কিন্তু বাস্তবায়নের অথবা উভয় ইন্টারফেস বাস্তবায়ন পারে আবার নাও পারে, তাই আমি বাছাই করতে হবে। (সরবরাহকারীর চেয়ে কারখানাটি বেশি সাধারণ বলে মনে হচ্ছে)।

কিছু কোড আমি ব্যবহারসমূহ দেখা করেছি অ জেনেরিক ILoggerইন্টারফেস এবং এমনকি একই এটির এক উদাহরণ হিসেবে বলা যায় ভাগ পারে, এবং কিছু একটি নিতে ILogger<T>তাদের ctor এবং খোলা জেনেরিক ধরনের বা প্রতিটি স্পষ্ট নিবন্ধন এবং প্রতি সমর্থন করার জন্য দ্বি ধারক আশা ILogger<T>প্রকরণ আমার লাইব্রেরিতে ব্যবহারসমূহ.

এই মুহুর্তে, আমি মনে করি ILogger<T>এটি সঠিক পদ্ধতির, এবং সম্ভবত এমন একটি কর্টার যা এই যুক্তিটি গ্রহণ করে না এবং কেবল পরিবর্তে একটি নাল লগার পাস করে। এইভাবে, যদি কোনও লগিংয়ের প্রয়োজন হয় না, কোনওটিই ব্যবহৃত হয় না। যাইহোক, কিছু ডিআই কনটেইনার বৃহত্তম কর্টোর বাছাই করে এবং যাইহোক এটি ব্যর্থ হবে।

আমি কি আমি করছি কৌতুহলী অনুমিত , ব্যবহারকারীদের জন্য মাথা ব্যাথা অন্তত পরিমাণ তৈরি করতে এখনও সঠিক লগিং সমর্থন, যার ফলে ইচ্ছা হলে এখানে কাজ করা হবে।

উত্তর:


113

সংজ্ঞা

আমরা 3 ইন্টারফেসগুলি আছে: ILogger, ILoggerProviderএবং ILoggerFactory। আসুন তাদের দায়িত্বগুলি খুঁজে পেতে উত্স কোডটি দেখুন :

ILogger : প্রদত্ত লগ স্তরের লগ বার্তা লেখার জন্য দায়বদ্ধ ।

আইলোগারপ্রাইডার : একটি দৃষ্টান্ত তৈরি করতে দায়বদ্ধ ILogger(আপনি ILoggerProviderকোনও লগার তৈরি করতে সরাসরি ব্যবহার করার কথা নয় )

আইলগারফ্যাক্টরি : আপনি ILoggerProviderকারখানার সাথে এক বা একাধিক গুলি নিবন্ধভুক্ত করতে পারেন , যা ফলস্বরূপ এগুলির একটি উদাহরণ তৈরি করতে ব্যবহার করে ILoggerILoggerFactoryএর একটি সংগ্রহ রয়েছে ILoggerProviders

নীচের উদাহরণে, আমরা কারখানার সাথে 2 সরবরাহকারী (কনসোল এবং ফাইল) নিবন্ধভুক্ত করছি। আমরা যখন কোনও লগার তৈরি করি তখন কারখানা লগার একটি উদাহরণ তৈরি করতে এই সরবরাহকারী উভয়টিকেই ব্যবহার করে:

ILoggerFactory factory = new LoggerFactory().AddConsole();    // add console provider
factory.AddProvider(new LoggerFileProvider("c:\\log.txt"));   // add file provider
Logger logger = factory.CreateLogger(); // <-- creates a console logger and a file logger

সুতরাং লোগার নিজেই, এর একটি সংগ্রহ বজায় রাখে ILogger, এবং এটি তাদের সকলের জন্য লগ বার্তাটি লিখে দেয়। লগার সোর্স কোডের দিকে তাকিয়ে আমরা নিশ্চিত করতে পারি যে Loggerএর ILoggersঅর্থ (যেমন LoggerInformation[]) রয়েছে এবং একই সাথে এটি ILoggerইন্টারফেস প্রয়োগ করছে ।


নির্ভরতা ইনজেকশন

এমএস ডকুমেন্টেশন লগার ইনজেকশন দেওয়ার জন্য 2 টি পদ্ধতি সরবরাহ করে:

1. কারখানা ইনজেকশন:

public TodoController(ITodoRepository todoRepository, ILoggerFactory logger)
{
    _todoRepository = todoRepository;
    _logger = logger.CreateLogger("TodoApi.Controllers.TodoController");
}

বিভাগ = টোডোপিপি.কন্ট্রোলার্স.ডোডো কন্ট্রোলার সহ একটি লগার তৈরি করে

২. জেনেরিক ইনজেকশন করা ILogger<T>:

public TodoController(ITodoRepository todoRepository, ILogger<TodoController> logger)
{
    _todoRepository = todoRepository;
    _logger = logger;
}

টোডো কনট্রোলারের ক্যাটাগরি = পুরোপুরি যোগ্য টাইপের নাম দিয়ে একটি লগার তৈরি করে


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

মার্ক সিমেনের মতে :

ইনজেকশন কনস্ট্রাক্টর নির্ভরতা প্রাপ্তির চেয়ে বেশি কিছু করা উচিত নয়।

কন্ট্রোলারে কোনও কারখানা ইনজেকশন করা ভাল পদ্ধতির নয়, কারণ লগার (আরআরপি লঙ্ঘন) আরম্ভ করার নিয়ামকের দায়িত্ব নয়। একই সাথে একটি জেনেরিক ইনজেকশনের ফলে ILogger<T>অপ্রয়োজনীয় আওয়াজ যুক্ত হয়। দেখুন সরল Injector এর : আরো বিস্তারিত জানার জন্য ব্লগে ASP.NET কোর দ্বি বিমূর্ততা নিয়ে কি ভুল?

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


এটি নিকোলা মালোভিচের একটি আর্টিকেল , যাতে তিনি তাঁর আইওসির 5 টি আইন ব্যাখ্যা করেছেন।

নিকোলার আইওসি-র 4 র্থ আইন

সমাধান করা শ্রেণীর প্রতিটি নির্মাণকারীর নিজস্ব নির্ভরতা একটি সেট গ্রহণ করা ব্যতীত অন্য কোনও প্রয়োগ করা উচিত নয়।


3
আপনার উত্তর এবং স্টিভেন এর নিবন্ধ একই সময়ে সবচেয়ে সঠিক এবং সবচেয়ে হতাশাজনক।
বোকিবেগ

30

সেগুলি ব্যতীত সমস্ত বৈধ ILoggerProviderILoggerএবং ILogger<T>লগিংয়ের জন্য আপনার ব্যবহার করার কথা। একটি পেতে ILogger, আপনি একটি ব্যবহার করুন ILoggerFactoryILogger<T>নির্দিষ্ট বিভাগের জন্য লগার পাওয়ার জন্য একটি শর্টকাট (বিভাগ হিসাবে ধরণের শর্টকাট)।

আপনি ILoggerলগিং সম্পাদন করতে ব্যবহার করার সময়, প্রতিটি নিবন্ধিত ILoggerProviderসেই লগ বার্তাটি হ্যান্ডেল করার সুযোগ পায়। ILoggerProviderসরাসরি কল করার জন্য কোড গ্রহণের ক্ষেত্রে এটি সত্যই বৈধ নয় ।


ধন্যবাদ। এটি আমার মনে করে যে ILoggerFactoryকেবলমাত্র 1 নির্ভরতা ( "আমাকে কেবল একটি কারখানা দিন এবং আমি আমার নিজস্ব লগার তৈরি করব" ) দ্বারা গ্রাহকদের জন্য ডিআই ওয়্যারিংয়ের সহজ উপায় হিসাবে দুর্দান্ত হয়ে উঠবে , তবে একটি বিদ্যমান লগার ব্যবহার করা আটকাবে ( যদি না ভোক্তা কিছু মোড়ক ব্যবহার করে)। একটি গ্রহণ ILogger- জেনেরিক বা না - ভোক্তা আমাকে একটা এটির তারা বিশেষভাবে প্রস্তুত দিতে পারবেন, কিন্তু সম্ভাব্য আরো অনেক জটিল (যদি না দ্বি ধারক যে সমর্থন ওপেন জেনেরিক্স ব্যবহার করা হয়) দ্বি সেটআপ করে তোলে। শব্দটি কি সঠিক? সেক্ষেত্রে আমার ধারণা আমি কারখানায় যাব।
মাইকেল স্টাম

3
@ মিশেলস্টাম - আমি নিশ্চিত নই যে আমি এখানে আপনার যুক্তি অনুসরণ করেছি। আপনি আপনার গ্রাহকরা একটি ডিআই সিস্টেম ব্যবহার করবেন বলে আশা করছেন কিন্তু তারপরে আপনি আপনার গ্রন্থাগারের মধ্যে নির্ভরতা পরিচালনা করতে এবং ম্যানুয়ালি পরিচালনা করতে চান? কেন এটি সঠিক পদ্ধতির বলে মনে হচ্ছে?
ড্যামিয়েন_এ_বিশ্বাসীরা

@ দামিয়েন_সে_ অবিশ্বাসী এটি একটি ভাল বিষয় point কারখানা নেওয়া অদ্ভুত বলে মনে হয়। আমি মনে করি যে এটি নেওয়ার পরিবর্তে ILogger<T>আমি একটি ILogger<MyClass>বা তার ILoggerপরিবর্তে গ্রহণ করব - এইভাবে ব্যবহারকারী কেবলমাত্র একটি রেজিস্ট্রেশন দিয়ে এবং তার ডিআই কনটেইনারটিতে খোলা জেনেরিকের প্রয়োজন ছাড়াই এটিকে ওয়্যার আপ করতে পারে। নন-জেনেরিকের দিকে ঝুঁকতে ILoggerথাকলেও উইকএন্ডে এটি প্রচুর পরীক্ষা করবে।
মাইকেল স্টাম

10

ILogger<T>প্রকৃত এক যে দ্বি জন্য তৈরি করা হয় ছিল। ILogger কারখানার প্যাটার্নটি আরও সহজেই বাস্তবায়নে সহায়তা করার জন্য এসেছিল, আপনি আপনার নিজের সমস্ত ডিআই এবং কারখানার যুক্তিতে লেখার পরিবর্তে, এটি এপ নেট কোরের অন্যতম স্মার্ট সিদ্ধান্ত ছিল।

আপনি এর মধ্যে চয়ন করতে পারেন:

ILogger<T>আপনার কোডে যদি কারখানা এবং ডিআই প্যাটার্নগুলি ব্যবহার করার প্রয়োজন হয় বাILogger ডিআইয়ের প্রয়োজন নেই এমন সাধারণ লগিং প্রয়োগ করতে আপনি এটি ব্যবহার করতে পারেন ।

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


1
ILogger বনাম ILogger <T> ডিআইয়ের সাথে কী করতে হবে? হয় তো ইনজেকশন লাগবে, না?
ম্যাথু হোস্টেলার

এটি আসলে এমএস ডক্সে আইলগার << বিভাগশ্রেণীর নাম>। এটি ILogger থেকে প্রাপ্ত এবং লগের জন্য শ্রেণীর নাম ব্যতীত কোনও নতুন কার্যকারিতা যুক্ত করে না। এটিও একটি অনন্য প্রকার সরবরাহ করে যাতে ডিআই সঠিকভাবে নামকরণকারী লগারটি ইনজেক্ট করে। মাইক্রোসফ্ট এক্সটেনশনগুলি অ-জেনেরিককে প্রসারিত করে this ILogger
স্যামুয়েল ড্যানিয়েলসন

8

এই প্রশ্নের সাথে লেগে থাকা, আমি বিশ্বাস করি ILogger<T>সঠিক বিকল্পটি, অন্যান্য বিকল্পগুলির খারাপ দিক বিবেচনা করে:

  1. ইনজেকশন ILoggerFactoryআপনার ব্যবহারকারীকে আপনার ক্লাস লাইব্রেরিতে পরিবর্তনীয় গ্লোবাল লগার ফ্যাক্টরির নিয়ন্ত্রণ ছেড়ে দিতে বাধ্য করে। তদুপরি, ILoggerFactoryআপনার ক্লাসটি গ্রহণ করে এখন CreateLoggerপদ্ধতিতে যেকোন স্বেচ্ছাসেবী বিভাগের নাম দিয়ে লগ করতে লিখতে পারেন । ILoggerFactoryসাধারণত ডিআই কন্টেইনারে সিঙ্গলটন হিসাবে উপলভ্য থাকাকালীন আমি কোনও ব্যবহারকারী হিসাবে সন্দেহ করব যে কোনও লাইব্রেরি কেন এটি ব্যবহার করতে হবে।
  2. পদ্ধতিটি ILoggerProvider.CreateLoggerদেখতে দেখতে দেখতে এটি ইঞ্জেকশনের জন্য নয়। এটি ILoggerFactory.AddProviderএমনটি ব্যবহার করা হয় যাতে ফ্যাক্টরি একত্রিত তৈরি করতে পারে ILoggerযা ILoggerপ্রতিটি নিবন্ধভুক্ত সরবরাহকারীর থেকে একাধিক তৈরিতে লিখে দেয় । আপনি বাস্তবায়ন পরিদর্শন করার সময় এটি স্পষ্ট হয়LoggerFactory.CreateLogger
  3. গ্রহণ ILoggerকরাও যাওয়ার পথে দেখায় বলে মনে হয় তবে। নেট কোর ডিআই দিয়ে এটি অসম্ভব। এটি ILogger<T>প্রথমে তাদের কেন সরবরাহ করার প্রয়োজনের কারণ বলে মনে হচ্ছে ।

সুতরাং সর্বোপরি, আমাদের ILogger<T>যদি এর চেয়ে ভাল কোনও পছন্দ নেই , যদি আমরা সেই ক্লাসগুলির মধ্যে থেকে বেছে নিই।

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


6

ডিফল্ট পদ্ধতির বোঝানো হয় ILogger<T>। এর অর্থ হ'ল লগে নির্দিষ্ট শ্রেণি থেকে লগগুলি স্পষ্টভাবে দৃশ্যমান হবে কারণ তারা প্রসঙ্গ হিসাবে পূর্ণ শ্রেণির নাম অন্তর্ভুক্ত করবে। উদাহরণস্বরূপ যদি আপনার শ্রেণীর পুরো নাম হয় MyLibrary.MyClassআপনি এই শ্রেণীর তৈরি লগ এন্ট্রিগুলিতে এটি পাবেন get উদাহরণ স্বরূপ:

মাইলিবারি.মাইক্লাস: তথ্য: আমার তথ্য লগ

আপনি ILoggerFactoryযদি নিজের প্রসঙ্গে নির্দিষ্ট করতে চান তবে আপনার এটি ব্যবহার করা উচিত । উদাহরণস্বরূপ আপনার লাইব্রেরি থেকে সমস্ত লগের পরিবর্তে প্রতিটি শ্রেণীর পরিবর্তে একই লগ প্রসঙ্গ রয়েছে। উদাহরণ স্বরূপ:

loggerFactory.CreateLogger("MyLibrary");

এবং তারপরে লগটি দেখতে এইরকম হবে:

মাই লাইব্রারি: তথ্য: আমার তথ্য লগ

আপনি যদি এটি সমস্ত ক্লাসে করেন তবে প্রসঙ্গটি সমস্ত শ্রেণীর জন্য কেবল মাই লাইব্রেরি হবে। আমি কল্পনা করি আপনি কোনও লাইব্রেরির জন্য এটি করতে চাইবেন যদি আপনি লগগুলিতে অভ্যন্তর শ্রেণীর কাঠামোটি প্রকাশ করতে না চান।

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

{
  "Logging": {
    "LogLevel": {
      "Default": "Warning",
      "MyLibrary": "None"
    }
  }
}

5

লাইব্রেরি ডিজাইনের জন্য ভাল পদ্ধতির হবে:

1. গ্রাহকদের আপনার ক্লাসে লগার ইনজেকশন করতে বাধ্য করবেন না। নুললগারফ্যাক্টরি পেরিয়ে কেবল অন্য একটি সিটি তৈরি করুন।

class MyClass
{
    private readonly ILoggerFactory _loggerFactory;

    public MyClass():this(NullLoggerFactory.Instance)
    {

    }
    public MyClass(ILoggerFactory loggerFactory)
    {
      this._loggerFactory = loggerFactory ?? NullLoggerFactory.Instance;
    }
}

২. ব্যবহারকারীরা লগগুলি সহজেই ফিল্টারিং কনফিগার করতে মঞ্জুরি দেওয়ার সময় আপনি ব্যবহার করেন এমন বিভাগগুলির সীমাবদ্ধ করুন। this._loggerFactory.CreateLogger(Consts.CategoryName)

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