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

نام تاپیک: چه طوری اینترفیس ها رو غیر از کلاس سازنده تعریف کنیم MVVM WPF

  1. #1
    کاربر دائمی
    تاریخ عضویت
    تیر 1390
    محل زندگی
    کرمانشاه
    پست
    1,487

    چه طوری اینترفیس ها رو غیر از کلاس سازنده تعریف کنیم MVVM WPF

    سلام وقت بخیر

    یک پروژه رو در حال تکمیل هستم که بعد از تعریف سرویس ها و اینترفیس هاشون ،، در قسمت viewModel ، داخل کانستراکتور ؛ اون اینترفیس ها رو صدا میزنیم و تعریف میکنیم. مشکل بنده اینه که : در کانستراکتور فرم HOME (که حاوی یک Drawer هست و فرم ها یا window ها رو از طریق این فرم صدا میزنیم ) اون اینترفیس ها و Entity ها رو صدا می زنیم به دلیل استفاده از Dependency Injection .

    مشکلی که دارم اینه که با باز شدن فرم Home ، تمام اون سرویس ها و دیتاسنگین دیتابیس، به دلیل اون Dependency Injection که در کانستراکتور لود شدن به یکباره لود میشن و بار سنگینی به سیستم میاد.

    به نظر شما، چه طوری میشه این اینترفیس ها رو زمانی که نیازشون داریم یا Window های مربوطه Show شدن یا Loaded شدن صدا زده بشه و دیتابگیره

    2.png1.png

  2. #2

    نقل قول: چه طوری اینترفیس ها رو غیر از کلاس سازنده تعریف کنیم MVVM WPF

    سلام
    من دقیق متوجه ی عملکردتون نشدم و بخشی از کدها هم توی عکس فرستادین .

    اما مشکلی نیست . خوب توی همون رویداد خاص ، عملیات مربوط به همون کاری که مد نظرتون هست را فراخوانی و اجرا کنین دیگه .

    ---------

    در کدتون که ساختار عملیاتی تون مشخص نیست .

    1 - مثلا در کدتون به نظر میرسه که یک کلاس ViewModel (در لایه ی ViewModel) با نام MainWindowViewModel داشته باشین . اگه این طور باشه ، حداقل به نظر من ، این ساختار درست نیست که به ازای یک Window ، بیاین یه ViewModel تعریف کنید . ViewModel ها باید به ازای هر ماژول ای که در لایه ی Model تعریف میشن ، تعریف بشن .
    مثلا اگر در Model ، 2 ماژول برای کار با ماژول اصلی برنامه تون که فرضا ماژول "انبارداری" و همچنین ماژول "اعتبارسنجی داده ها" دارین ، در ViewModel هم معمولا 2 تا به ازای هر کدوم از اونها درست میکنن (گاها ممکنه به ازای چند ماژول ، فقط یک ViewModel درست بشه) .

    2 - باز هم به نظر میرسه که در ViewModel (در سازنده ی ItemViewModel) ، شی ای از Repository ها دریافت کرده باشین را از لایه ی View دریافت کرده باشین (نوع IAsyncRepository<T>) .
    اگر این طور باشه ، کلا معماری لایه ای را نقض کردین (نه فقط MVVM را) چون Repository که حداقل در لایه ی Model قرار میگیره و View نمیتونه شی ای از لایه ی Model را در اختیار ViewModel بذاره یا ازش بگیره . اگر بقیه ی انواع داده ای که در اون سازنده ها هستند هم همین روال را داشته باشند هم ، همین داستان براشون برقرار هست .

    در هر معماری لایه ای ، فقط (کلاس های) لایه ی قبلی میتونه برای (کلاس های) لایه ی بعدی ، داده ارسال و ازش دریافت کنه .
    لایه ی بعدی هم اگه اطلاعاتی بخواد به لایه ی قبلی بفرسته ، یا باید توسط متد بازگشتی ، یا باید توسط رویداد و یا Binding باشه . یعنی لایه ی بعدی (مثل Model) ، نمیتونه از لایه ی قبلی (مثل ViewModel) ، شی بسازه یا به کلاس هایی که در لایه ی قبلی تعریف میشه ، دسترسی داشته باشه .

    3 - Dependency Injection به این معنا نیست که شی ای از لایه بعدی (مثل Model) را از دو لایه ی قبلی (مثل View) دریافت کنید (وگرنه کلا معماری لایه ای ، نقض میشه) .
    بلکه به این معناست که نهایتا فرضا شی ای از کلاس های لایه ی بعدی را از لایه ی قبلی دریافت کنید . حتی میتونه ربطی به این هم نداشته باشه و از کلاس هایی که در همون لایه هستند ، دریافت کنید .

    ضمنا ، به نظرم الگوی طراحی ای که جایگزین خوبی برای Dependency Injection باشه ، الگوی طراحی Factory Method یا Service Locator هستند .
    میتونید در همون ماژول ای که اینترفیسی را برایش طراحی میکنید ، یک کلاسی (فرضا بنام ServiceLocator) بسازید که شی ای از یک کلاسی که اون اینترفیس درون اون ماژول را پیاده سازی میکنند ، بسازه .
    بعد هم در لایه و یا در ماژول دیگه ای که میخواین از این ماژول استفاده کنین ، نوع داده ای را از نوع اینترفیس و شی را از متدی از کلاس ServiceLocator بگیرین که شی ای از کلاس های اون ماژول را برمیگردوند :


    //Modual Test
    public interface ITest
    {

    }


    public class TestA
    {

    }


    public class TestB
    {

    }


    //ServiceLocator
    public class ServiceLocator
    {
    public static ITest GetTestA()
    {
    return new TestA();
    }
    }




    // Other Modual
    public class Use
    {
    private void Name()
    {
    ITest test = ServiceLocator.GetTestA();
    }
    }


    کدهای کامل و کلا درباره ی این الگوهای طراحی میتونید در اینترنت جستجو کنید .

    4 - برای رعایت اصل SRP در Solid ، همه ی کارها را درون یک متد (و حتی یک کلاس) انجام ندید . متد سازنده تون ، پر از کارهای مختلف هست . از مقداردهی اولیه ، تا شی سازی Command ها و ... . حداقل شی سازی Command را در متد مجزا بنویسید و در متد سازنده فراخوانی کنید .

    5 - در عکس دوم ، مقداردهی IsLoading چرا در نخ جدید ، اون هم با توقف 1 ثانیه انجام گرفت؟!
    نخ جدید را معمولا برای کارهای سنگین ، یا کاری که UI را منتظر نذاره ، انجام میدن . به نظر میرسه که این کدتون در نخ جدید ، روی هیچ کدوم از این نوع کارها تاثیری نداره .

  3. #3
    کاربر دائمی
    تاریخ عضویت
    تیر 1390
    محل زندگی
    کرمانشاه
    پست
    1,487

    نقل قول: چه طوری اینترفیس ها رو غیر از کلاس سازنده تعریف کنیم MVVM WPF

    نقل قول نوشته شده توسط SajjadKhati مشاهده تاپیک
    سلام
    من دقیق متوجه ی عملکردتون نشدم و بخشی از کدها هم توی عکس فرستادین .

    اما مشکلی نیست . خوب توی همون رویداد خاص ، عملیات مربوط به همون کاری که مد نظرتون هست را فراخوانی و اجرا کنین دیگه .

    ---------

    در کدتون که ساختار عملیاتی تون مشخص نیست .

    1 - مثلا در کدتون به نظر میرسه که یک کلاس ViewModel (در لایه ی ViewModel) با نام MainWindowViewModel داشته باشین . اگه این طور باشه ، حداقل به نظر من ، این ساختار درست نیست که به ازای یک Window ، بیاین یه ViewModel تعریف کنید . ViewModel ها باید به ازای هر ماژول ای که در لایه ی Model تعریف میشن ، تعریف بشن .
    مثلا اگر در Model ، 2 ماژول برای کار با ماژول اصلی برنامه تون که فرضا ماژول "انبارداری" و همچنین ماژول "اعتبارسنجی داده ها" دارین ، در ViewModel هم معمولا 2 تا به ازای هر کدوم از اونها درست میکنن (گاها ممکنه به ازای چند ماژول ، فقط یک ViewModel درست بشه) .

    2 - باز هم به نظر میرسه که در ViewModel (در سازنده ی ItemViewModel) ، شی ای از Repository ها دریافت کرده باشین را از لایه ی View دریافت کرده باشین (نوع IAsyncRepository<T>) .
    اگر این طور باشه ، کلا معماری لایه ای را نقض کردین (نه فقط MVVM را) چون Repository که حداقل در لایه ی Model قرار میگیره و View نمیتونه شی ای از لایه ی Model را در اختیار ViewModel بذاره یا ازش بگیره . اگر بقیه ی انواع داده ای که در اون سازنده ها هستند هم همین روال را داشته باشند هم ، همین داستان براشون برقرار هست .

    در هر معماری لایه ای ، فقط (کلاس های) لایه ی قبلی میتونه برای (کلاس های) لایه ی بعدی ، داده ارسال و ازش دریافت کنه .
    لایه ی بعدی هم اگه اطلاعاتی بخواد به لایه ی قبلی بفرسته ، یا باید توسط متد بازگشتی ، یا باید توسط رویداد و یا Binding باشه . یعنی لایه ی بعدی (مثل Model) ، نمیتونه از لایه ی قبلی (مثل ViewModel) ، شی بسازه یا به کلاس هایی که در لایه ی قبلی تعریف میشه ، دسترسی داشته باشه .

    3 - Dependency Injection به این معنا نیست که شی ای از لایه بعدی (مثل Model) را از دو لایه ی قبلی (مثل View) دریافت کنید (وگرنه کلا معماری لایه ای ، نقض میشه) .
    بلکه به این معناست که نهایتا فرضا شی ای از کلاس های لایه ی بعدی را از لایه ی قبلی دریافت کنید . حتی میتونه ربطی به این هم نداشته باشه و از کلاس هایی که در همون لایه هستند ، دریافت کنید .

    ضمنا ، به نظرم الگوی طراحی ای که جایگزین خوبی برای Dependency Injection باشه ، الگوی طراحی Factory Method یا Service Locator هستند .
    میتونید در همون ماژول ای که اینترفیسی را برایش طراحی میکنید ، یک کلاسی (فرضا بنام ServiceLocator) بسازید که شی ای از یک کلاسی که اون اینترفیس درون اون ماژول را پیاده سازی میکنند ، بسازه .
    بعد هم در لایه و یا در ماژول دیگه ای که میخواین از این ماژول استفاده کنین ، نوع داده ای را از نوع اینترفیس و شی را از متدی از کلاس ServiceLocator بگیرین که شی ای از کلاس های اون ماژول را برمیگردوند :


    //Modual Test
    public interface ITest
    {

    }


    public class TestA
    {

    }


    public class TestB
    {

    }


    //ServiceLocator
    public class ServiceLocator
    {
    public static ITest GetTestA()
    {
    return new TestA();
    }
    }




    // Other Modual
    public class Use
    {
    private void Name()
    {
    ITest test = ServiceLocator.GetTestA();
    }
    }


    کدهای کامل و کلا درباره ی این الگوهای طراحی میتونید در اینترنت جستجو کنید .

    4 - برای رعایت اصل SRP در Solid ، همه ی کارها را درون یک متد (و حتی یک کلاس) انجام ندید . متد سازنده تون ، پر از کارهای مختلف هست . از مقداردهی اولیه ، تا شی سازی Command ها و ... . حداقل شی سازی Command را در متد مجزا بنویسید و در متد سازنده فراخوانی کنید .

    5 - در عکس دوم ، مقداردهی IsLoading چرا در نخ جدید ، اون هم با توقف 1 ثانیه انجام گرفت؟!
    نخ جدید را معمولا برای کارهای سنگین ، یا کاری که UI را منتظر نذاره ، انجام میدن . به نظر میرسه که این کدتون در نخ جدید ، روی هیچ کدوم از این نوع کارها تاثیری نداره .
    سلام وقت بخیر

    این تصاویر از ساختار برنامه بنده است. لطفا یه بررسی بکنید

    1.png2.png3.png4.png




    ببینید چیزی که طراح UI انجام داده و گفتن WPF اینطوریه ، برای هر Window یه ViewModel ساختن و بیزینس پروژه و کد نویسی ها داخلش انجام میشه. ارتباط با دیتابیس و فراخوانی و CRUD و ..... .

    بالاتر هم در Application ، سرویس ها و Interface ها استفاده شدن . البته تمام تلاش بنده اینه که فقط از اینترفیس ها استفاده کنم .

    مشکلی که الان بنده دارم اینه که مثلا داخل MainWindowViewModel ، تمامی فرم ها رو برای اینکه یک شی ازشون بسازم و صدا بزنم در سازنده نمونه سازی کردم، و الان کل دیتابیس رو صدا میزنه و دیتاسنگینی شده که اصلا اصولی نیست .

    هدفم اینه به روشی برسم که بتونم هر فرم یا ویندو که باز بشه ، اون زمان دیتا مربوطه اش فراخوانی بشه .

    در حال حاضر امکان ریفکتور کردن خیلی ندارم ، ولی قطعا در آینده اینکار انجام میدم .

  4. #4

    نقل قول: چه طوری اینترفیس ها رو غیر از کلاس سازنده تعریف کنیم MVVM WPF

    نقل قول نوشته شده توسط NasimBamdad مشاهده تاپیک
    سلام وقت بخیر

    این تصاویر از ساختار برنامه بنده است. لطفا یه بررسی بکنید

    ببینید چیزی که طراح UI انجام داده و گفتن WPF اینطوریه ، برای هر Window یه ViewModel ساختن و بیزینس پروژه و کد نویسی ها داخلش انجام میشه. ارتباط با دیتابیس و فراخوانی و CRUD و ..... .
    سلام
    وقت بخیر .

    اول اینکه که چیزی که میگید ، ربطی به WPF نداره .
    به معماری نرم افزار ربط داره . معماری ها هم مختلف هست که بسته به هر معماری (البته اگه معماریِ لایه ای باشه) ، لایه های مختلفی که هر کدوم شون وظایف مختلفی دارند ، دارند .
    از معماری Clean گرفته (که شامل لایه های Presentation و Use Cases و Domain و Data و Framework) ، تا معماری جاری ای که در اغلب اپلیکیشن های Winform که 3 لایه ی Presentation و Business Logic و Data Access داره گرفته ، تا معماری MVVM و ... .

    اینکه معماری MVVM را بصورت ساختاری که میگید ، تفسیر میکنید را حداقل اینکه من این جور ساختار را و مخصوصا نمونه کدهاش را کمتر دیدم .
    بیشتر ، ساختار MVVM را بصورت زیر دیدم که لایه ی Model ، مسئول اصلی و اغلبِ همون کاری که وظیفه ی لایه ی Business Logic بود ، مسئولیت اش با لایه ی Model در این معماری هست :

    MVVM In WPF (c-sharpcorner.com)

    البته در این معماری MVVM ، میتونه لایه ی Data Access ای هم وجود نداشته باشه و بنابراین این لایه ، با لایه ی Model ترکیب شده باشه و بنابراین لایه ی ViewModel ، مستقیما بتونه با (دسترسی به) دیتابیس ، ارتباط داشته باشه .

    هر چند بسته به پروژه ولی من معمولا ترجیح میدم که در MVVM هم یه لایه ی Data Access بسازم که فقط Model باهاش ارتباط داشته باشه (یعنی ViewModel ، مستقیما باهاش در ارتباط نباشه ؛ شبیه به لایه ی Business Logic که فقط این لایه با Data Access در تماس هست) .

    ViewModel هم فقط وظیفه ی انتقال اطلاعات از View به Model را داره .

    ======

    هر یک از وظایف این لایه ها که مشخص شد .
    اما ساختار برنامه نویسی ای که انجام میدم اینه که در هر یک از این لایه ها ، ماژول هایی که میسازم ، با یک ماژولِ دیگه که در لایه ی قبلی وجود داره ، در ارتباط باشه (ممکنه این طور هم بشه که فقط یک ماژول ، با چند ماژول در لایه ی بعد ، یا در همون لایه در ارتباط باشه) .

    یعنی این طور پیش نمیرم که به ازای هر یک Window ، یک کلاس در ViewModel که اون هم همه ی کارهای منطق تجاری را انجام بده ، درست کنم .
    مثلا ممکنه یه MainWindow فقط داشته باشیم که همون یه پنجره ، 100 تا کارهای کاملا متفاوت را انجام بده . ابزارهای متفاوت داشته باشه و ... . مثل اغلب نرم افزارهایی که میبینید . از فتوشاپ ، تا افترافکت تا ویژال استودیو گرفته که فقط در صفحه ی اصلی شون (از طریق منوها یا هر آیکون یا هر پنل و ...) ، کلی کارهای گاها کاملا متفاوت میشه انجام داد که ممکنه اصلا ربطی به هم نداشته باشند .

    در این صورت ، به نظرم وقتی به ازای یک صفحه از همچین نرم افزاری (یا هر نرم افزاری) ، این طوری طراحی بشه ، کدها ، بسیار پیچیده و ماژولاریتی برنامه بسیار پایین و تغییر در کدها بسیار سخت میشه .

    البته نمیخوام منکر این نوع طراحی بشم . ممکنه (و احتمالا) در معماری های دیگه ، همچین طراحی ای هم وجود داشته باشه (مثلا شاید معماری clean این طور باشه . مثال گفتم ، نه اینکه حتما هست . چون به این معماری آشنا نیستم) .

    اما حداقل تا جایی که میدونم ، معماری MVVM این طور نیست و وظایف لایه هاش هم اون طورن که گفته شد . اما باز هم ممکنه بسته به دید طراح و معمار نرم افزارتون داشته باشه .

    نقل قول نوشته شده توسط NasimBamdad مشاهده تاپیک
    بالاتر هم در Application ، سرویس ها و Interface ها استفاده شدن . البته تمام تلاش بنده اینه که فقط از اینترفیس ها استفاده کنم .

    همونطور که گفتم ، اما ممکنه بسته به دید طراح و معمار نرم افزارتون داشته باشه . مثلا ممکنه که تیم توسعه ی نرم افزاری (یا نرم افزارتون) ، ترکیبی از چند معماری ، یا معماری شخصی سازی شده را ترجیح بدن .


    نقل قول نوشته شده توسط NasimBamdad مشاهده تاپیک

    مشکلی که الان بنده دارم اینه که مثلا داخل MainWindowViewModel ، تمامی فرم ها رو برای اینکه یک شی ازشون بسازم و صدا بزنم در سازنده نمونه سازی کردم، و الان کل دیتابیس رو صدا میزنه و دیتاسنگینی شده که اصلا اصولی نیست .

    گفتم که .
    من با معماری ای که پیاده سازی کردید ، آشنایی ندارم .
    ممکنه که طراح و معمار نرم افزارتون ، MVVM را ترکیبی با یک معماری دیگه (یا ترکیبی با معماری شخصی خودش) هم کرده باشه اما تا جایی که میدونم ، معماریِ خالصِ MVVM ، این طوری نیست .

    در MVVM ، هیچ مشکلی وجود نداره که در رویدادتون ، یک Command ای که در ViewModel تعریف شده را از View فراخوانی کنید .
    اگه معماری تون فقط MVVM باشه ، برای حل مشکل تون ، 2 نمونه کدی که در لینک زیر هست ، به دردتون میخوره :

    سئوال درباره Command (barnamenevis.org)


    نقل قول نوشته شده توسط NasimBamdad مشاهده تاپیک
    هدفم اینه به روشی برسم که بتونم هر فرم یا ویندو که باز بشه ، اون زمان دیتا مربوطه اش فراخوانی بشه .

    در حال حاضر امکان ریفکتور کردن خیلی ندارم ، ولی قطعا در آینده اینکار انجام میدم .
    از رویداد استفاده کنید (البته گفتم که به معماری شما آشنا نیستم) .

  5. #5
    کاربر دائمی
    تاریخ عضویت
    تیر 1390
    محل زندگی
    کرمانشاه
    پست
    1,487

    نقل قول: چه طوری اینترفیس ها رو غیر از کلاس سازنده تعریف کنیم MVVM WPF

    درود و سپاس برای موارد مفید شما
    طبق بررسی های بنده ، اینکه در کلاس سازنده ، سرویس ها و Entity ها تعریف میشن هیچ مشکلی ایجاد نمیکنه ، و عملا کلاس سی شارپی اون ها بدون دیتا رو بهشون معرفی میکنه که سرباری نداره

    مشکل بنده اونجا بود که در سازنده اقدام به پر کردن آن ها می کردم، که با حذف این کار و انتقال آن به رویداد های مناسب شان مشکل حل شد

  6. #6

    نقل قول: چه طوری اینترفیس ها رو غیر از کلاس سازنده تعریف کنیم MVVM WPF

    نقل قول نوشته شده توسط NasimBamdad مشاهده تاپیک
    درود و سپاس برای موارد مفید شما
    طبق بررسی های بنده ، اینکه در کلاس سازنده ، سرویس ها و Entity ها تعریف میشن هیچ مشکلی ایجاد نمیکنه ، و عملا کلاس سی شارپی اون ها بدون دیتا رو بهشون معرفی میکنه که سرباری نداره

    مشکل بنده اونجا بود که در سازنده اقدام به پر کردن آن ها می کردم، که با حذف این کار و انتقال آن به رویداد های مناسب شان مشکل حل شد
    سلام
    پست ۲ ، در دو خطِ اولش (و همچنین در جاهای دیگه) ، همین را گفته بودم که عملیات مورد نظرتون را در رویداد مورد نظرتون اجرا کنید دیگه .

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

  1. سوال: چرا توی mvvm باید کنترلها داخل user control تعریف شه؟
    نوشته شده توسط سیدسبحان در بخش WPF
    پاسخ: 5
    آخرین پست: پنج شنبه 03 دی 1394, 19:49 عصر
  2. پاسخ: 0
    آخرین پست: شنبه 05 مهر 1393, 22:53 عصر
  3. پاسخ: 0
    آخرین پست: سه شنبه 31 تیر 1393, 17:42 عصر
  4. مبتدی: MvvM و دیتابیس
    نوشته شده توسط hadinajafi در بخش Silverlight
    پاسخ: 1
    آخرین پست: جمعه 16 اسفند 1392, 15:33 عصر
  5. آموزش: تعداد عناصر غیر صفر در یک ماتریس مربعی nxn
    نوشته شده توسط nefrat در بخش الگوریتم، کامپایلر، هوش مصنوعی و ساختمان داده ها
    پاسخ: 0
    آخرین پست: سه شنبه 18 مرداد 1390, 18:11 عصر

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

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