نمایش نتایج 1 تا 6 از 6

نام تاپیک: DI و کانستراکتور در ASP.NET Core 2

  1. #1

    DI و کانستراکتور در ASP.NET Core 2

    سلام دوستان.
    من درمورد DI جست و جو کردم و همه جا نوشته بودن که برای ماژولار شدن و از بین بردن وابستگی بین کلاس هاست ولی من هرجور میبینم کلاسهای من وایسته تر دارن میشن.
    من یک DbContext دارم که به این صورت هست :
    publicBlogDbContext(DbContextOptions<BlogDbContext> options)
    : base(options){}

    حالا توی کنترلر میخوام استفاده کنم مشکلی نداره ولی مشکل اینجا پیش میاد که میخوام یک کلاس دیگه (Logic) داشته باشم که توابعم رو اونجا داشته باشم و توی کنترلرها صدا بزنم، مثال میزنم :
    من همیشه برای لاگ گرفتن کارها توی سایت یه جدول دارم با عنوان لاگ و یه کلاس تو پوشه ی لاجیک به اسم ActivityLogger.cs توی این یک تابع دارم که دیتا اینسرت میکنه تو جدول لاگها، بعد توی کنترلر ها وقتی میخوام کاری انجام بدم از بلاک Try-Catch استفاده میکنم و توی Catch تابع اسنرتی که توی ActivityLogger بود رو صدا میزنم تا خطا رو ثبت کنه.
    حالا برای اینکار مثل همیشه (که تو وب فرم کار میکردم) کدهای کلاس ActivityLogger.cs رو میخوام بنویسم، این کلاس کانستراکتور داره که ورودیش DbContext هست و IHttpContextAccessor برای بدست آوردن کانتکس و از اون نام کاربری کاربر لاگین هست :
    privatereadonlyBlogDbContext db;        private readonly IHttpContextAccessor context;
    public ActivityLogger(IHttpContextAccessor _context,BlogDbContext _db)
    {
    context = _context;
    db = _db;

    }

    حالا وقتی میخوام از این تابع استفاده کنم خوب باید یه اینستنس از ActivityLogger.cs دزست کنم و بخاطر کانستراکتور باید ورودی هم بهش بدم (این که وابستگیش بیشتر شد، قبلا تو خود کلاس از دی بی کانتکس یه نمونه درست میکردم و همه کارها رو میکردم دیگه لازم نبود بهش پاس بدم) حالا اگر بخوام توی خود کلاس ActivityLogger.cs یه اسنستنس از DbContext بسازم نمیشه و خطا میده :
    کد HTML:
    There is no argument given that corresponds to the required formal parameter 'options' of 'BlogDbContext.BlogDbContext(DbContextOptions<BlogDbContext>)
    با این وضعیت که من دارم میبینم DI و کانستراکتور کار منو سخت تر کردن که، از طرفی من دارم همه ش dbContext رو پاس میدم بهشون شما فکن دو سه تا کلاس پشت هم باشه این نمونه از DbContext تا دو سه تا کلاس همینطوری جلو میره.
    میشه یکی بهم توضیح بده اصلا این جریانش چیه؟ کجا رو دارم اشتباه میکنم؟

  2. #2

    نقل قول: DI و کانستراکتور در ASP.NET Core 2

    کدهاتون درست قرار داده نشده نمیشه خوند .

    - درباره تزریق وابستگی
    وابستگی های یک کلاس رو شما با Constructor Injection و یا Property Injection تزریق میکنید و برای تزریق از یکی از IoC Container ها استفاده میکنید. ( Ninject, AutoFac, Castle Windsor, ... )

    هیچوقت نمیشه که وابستگی در سیستم شما به 0 برسه ;
    بعنوان مثال شما یک ILogger میسازید اما بالاخره یکجایی نیاز به new کردن context در یک کلاس دارید تا در برنامتون از دیتابیس استفاده کنید مثل Implementation کلاس IRepository تون ، پس وابستگی هست - در DI سعی بر این هست که شما این وابستگی ها رو " حداقل " کنید اما 0 امکان پذیر نیست.


    - مبحث دیگه ای که وجود داره YAGNI Principle که مخفف You Aren't Gonna Need It هست.

    این قانون میگه :
    "Always implement things when you actually need them, never when you just foresee that you need them"
    معناش این هست که تا وقتی که واقعا به یک چیزی " نیاز " پیدا نکردید ، لازم نیست اون رو در برنامتون پیاده سازی کنید .
    تا وقتی احساس نکردید که نیاز به استفاده از این موارد دارید لازم نیست خودتون رو درگیر پیاده سازیش تو برنامتون کنید.


    -برای پیاده سازی Loggerتون هم :
    میتونید یک interface برای IRepository داشته باشید که Generic باشه و متد های ارتباط با دیتابیس رو داشته باشه و یک کلاس Repository که پیاده سازی IRepository هست که Context شما داخلش تعریف میشه و متد ها پیاده سازی میشن ( Add, Delete, Update, Get, GetAll )
    بعد از پیاده سازی این 2 ، میتونید از با استفاده از DI از IRepository داخل Logger تون برای ذخیره سازی لاگ ها داخل دیتابیس استفاده کنید.

    Logger پیشفرض خود ASP.NET Core رو هم فراموش نکنید.

  3. #3

    نقل قول: DI و کانستراکتور در ASP.NET Core 2

    بله كاملا درسته، تا حدودی كارم راه افتاد.
    داكیومنشن خود مایكروسافت رو خوندم فهمیدم مشكل من این بود كه اینترفیس تعریف نمیكرردم و توی فایل startup.cs سرویسم رو معرفی نمیكردم.
    ببینید الان یك سوال دارم، تو همین لاگر خودم من یك كانتكست كه مال دیتابیس هست لازم دارم و یكی هم IHttpContextAccessor كه بتونم به كمك متد currentcontext.user نام كاربریكاربر و بدست بیارم، خوب پس تو ورودی كانستراكتور این كلاس باید هم dbcontext باشه هم ihttpcontextaccessor مثلا دوتا تابع دارم یكی برای ثبت لاگ یكی برایواكشی لاگ ها كه توی ثبت به هر دو ورودی نیاز دارم اما توی تابع واكشی فقط به دی بی كانتكس نیاز دارم.
    حالا سوال اینجاست وقتی میخام از این استفاده كنم مینویسم:
    Var logger = new Logger(db,ctx);
    خوب من الان بخام تابع واكشی رو صدا بزنم نیازی به ctx ندارم و فقط همون db رو باید پاس بدم ولی چون توی ورودی های Contrutor IHttpContextAccessor رو هم تعریف کردم مجبورم اینم پاس بدم
    دقیقا سوال من اینه که این کار درسته؟ یا شاید من دارم اشتباه انجام میدم.
    من کلی مطلب درباره همین DI خوندم همه شون گفتن برای کم کردن وابستگی هست، مثالهای قشنگی هم زدن اما وقتی خودم میرم توی کار به همچین مشکلی میخورم.
    یه سوال دیگه اینکه میشه یه راهنمایی دریاره ILogger خودش بکنید؟ یه منبع روان تر اگه باشه بگید خودم میخونم مزاحم شما نمیشم.
    ممنون

  4. #4

    نقل قول: DI و کانستراکتور در ASP.NET Core 2

    در مورد Logger ای که دارید درست میکنید ; لازم نیست db رو به logger پاس بدید و حتی میتونید قبلش username کاربر رو بگیرید و بعد به logger پاس بدید .

    شما میتونید یک interface بسازید به اسم ILogger که یک متد Log داشته باشه :


    public interface ILogger
    {
    void Log(Log log);
    }



    این interface رو میتونید به شکل های مختلف پیاده سازی کنید ; مثلا یه لاگ داشته باشید که داخل دیتابیس ثبت بشه ، یه لاگ داخل فایل text ذخیره بشه و ...

    بعوان مثال ، پیاده سازی ILogger برای ذخیره لاگ در database :


    public class Log
    {
    [Key]
    public int ID { get; set; }

    [Required]
    public string message { get; set; }
    }


    public interface ILogger
    {
    void Log(Log log);
    }


    public class DbLogger : ILogger
    {
    private readonly IGenericRepository<Log> _loggerRepository;
    private readonly IUnitOfWork _unitOfWork;

    public DbLogger(IRepository<Log> loggerRepository, IUnitOfWork unitOfWork)
    {
    _loggerRepository = loggerRepository;
    _unitOfWork = unitOfWork;
    }

    public void Log(Log log)
    {
    Log log = new Log
    {
    Message = message
    };

    _loggerRepository.Add(log);
    _unitOfWork.Save();
    }
    }



    به این شکل شما حداقل وابستگی رو دارید.
    IRepository و IUnitOfWork رو اگر ازشون اطلاع ندارید ، 2 Design Pattern هستن که بنده بصورت Generic ساختمشون که به Logger تزریق شدن و کارشون ارتباط با دیتابیس هست.

    میتونید دربارشون اینجا مطالعه کنید :
    https://msdn.microsoft.com/en-us/magazine/mt703433.aspx
    https://www.infragistics.com/communi...plication.aspx


    یه سوال دیگه اینکه میشه یه راهنمایی دریاره ILogger خودش بکنید؟
    https://stackify.com/asp-net-core-logging-what-changed/
    آخرین ویرایش به وسیله Moien Tajik : یک شنبه 30 مهر 1396 در 22:31 عصر

  5. #5

    نقل قول: DI و کانستراکتور در ASP.NET Core 2

    خدا پدرتو بیامرده، همه چیزو گفتی اصل مطلب رو نگفتی:
    اولا نیاز نیست سرویسش رو تو استارت آپ.سی اس معرفی كنم؟ اگه نیازه چطوری؟

    دوما حالا میخوام ازش تو یه اكشنی مثلا استفاده كنم، چطور باید استفاده كنم؟
    Var lg = new DbLogger(params);
    تا اینجا اوكیه ورودی ها رو كه میخوام بددم مثلا unitofwork رو میخوام نیو كنم تو اكشن نمیشه كه باید یه پابلیك بالای كنترلر درست كنم از نوع یونیت او ورك و توی كانستراكتور خود كنترلر مقدارددهی كنم و بعد تو اكشن اونو به عنوان ورودی به lg پاس بدم ددرسته؟

  6. #6

    نقل قول: DI و کانستراکتور در ASP.NET Core 2

    اول - همه ی سرویس هارو باید در استارت آپ معرفی کنید.
    دوم - هر وقت نیاز به یک سرویس درون یک کنترلر دارید باید اون سرویس رو در Constructor کلاس تزریق کنید. باید یک سازنده از نوع پالیک بسازید و به همون شیوه ای که گفتید شی رو تعریف کنید.
    نیازی نیست که همه کلاسهای وابسته اون کلاس رو هم تعریف کنید. سیستم تزریق وابستگی خودش وابستگی های بعدی رو زنجیر وار پیدا میکنه و اضافه میکنه.

تاپیک های مشابه

  1. سوال: اضافه کردن مدل در asp.net core 1
    نوشته شده توسط gama_slv در بخش ASP.NET MVC
    پاسخ: 3
    آخرین پست: دوشنبه 03 خرداد 1395, 23:45 عصر
  2. نحوه ارسال ایمیل در ASP.NET Core 1.0
    نوشته شده توسط mona.rostami در بخش ASP.NET Web Forms
    پاسخ: 0
    آخرین پست: دوشنبه 16 فروردین 1395, 02:35 صبح

قوانین ایجاد تاپیک در تالار

  • شما نمی توانید تاپیک جدید ایجاد کنید
  • شما نمی توانید به تاپیک ها پاسخ دهید
  • شما نمی توانید ضمیمه ارسال کنید
  • شما نمی توانید پاسخ هایتان را ویرایش کنید
  •