بهتر است برای Parse دقیقتر تاریخ شمسی، از متدهای الحاقی ToGregorianDateTime و IsValidPersianDateTime استفاده کنید که حالتهای بیشتری را پوشش میدهند و نیازی به این if/elseها دیگر نخواهد بود.
نظرات مطالب
مدیریت سفارشی سطوح دسترسی کاربران در MVC
مطالب دورهها
تزریق وابستگیها
خوب! بالاخره بعد از دو قسمت قبل، به بحث اصلی تزریق وابستگیها رسیدیم. بحثی که بسیاری از برنامه نویسهای تصور میکنند همان IoC است که پیشتر در مورد آن بحث شد.
تزریق وابستگیها یا DI چیست؟
تزریق وابستگیها یکی از انواع IoC بوده که در آن ایجاد و انقیاد (binding) یک وابستگی، در خارج از کلاسی که به آن نیاز دارد صورت میگیرد. روشهای متفاوتی برای ارائه این وابستگی وهله سازی شده در خارج از کلاس به آن وجود دارد که در ادامه مورد بررسی قرار خواهند گرفت.
یک مثال: بسته غذایی را که با خود به سر کار میبرید درنظر بگیرید. تمام اجزای مورد نیاز تشکیل دهنده یک بسته غذا عموما داخل آن قرار گرفته و حمل میشوند. حالت عکس آن زمانی است که در محل کار به شما غذا میدهند. این دقیقا همان حالتی است که تزریق وابستگیها کار میکند؛ یک سری سرویسهای خارجی، نیازهای کلاس جاری را برآورده میسازند.
در تصویر فوق یک طراحی مبتنی بر معکوس سازی کنترلها را مشاهده میکنید. وابستگیهای یک کلاس توسط اینترفیسی مشخص شده و سپس کلاسی وجود دارد که این وابستگی را پیاده سازی کرده است.
همچنین در این تصویر یک خط منقطع از کلاس MyClass به کلاس Dependency رسم شده است. این خط، مربوط به حالتی است که خود کلاس، مستقیما کار وهله سازی وابستگی مورد نیاز خود را انجام دهد؛ هر چند اینترفیسی نیز در این بین تعریف شده باشد. بنابراین اگر در بین کدهای این کلاس، چنین کدی مشاهده شد:
تعریف dependency از نوع IDependency به معنای معکوس سازی کنترل نبوده و عملا همان معماری سابق و متداول بکارگرفته شده است. برای بهبود این وضعیت، از تزریق وابستگیها کمک خواهیم گرفت:
در اینجا یک کلاس دیگر به نام Injector اضافه شده است که قابلیت تزریق وابستگیها را به کلاس نیازمند آن به روشهای مختلفی دارا است. کار کلاس Injector، وهله سازی MyClass و همچنین وابستگیهای آن میباشد؛ سپس وابستگی را دراختیار MyClass قرار میدهد.
تزریق وابستگیها در سازنده کلاس
یکی از انواع روشهای تزریق وابستگیها، Constructor Injection و یا تزریق وابستگیها در سازنده کلاس میباشد که متداولترین نوع آنها نیز بهشمار میرود. در این حالت، وابستگی پس از وهله سازی، از طریق پارامترهای سازنده یک کلاس، در اختیار آن قرار میگیرند.
یک مثال:
در اینجا شما یک کلاس خریدار را مشاهده میکنید که وابستگی مورد نیاز خود را به شکل یک اینترفیس از طریق سازنده کلاس دریافت میکند.
برای نمونه، وهلهای از مستر کارتی که ICreditCard را پیاده سازی کرده باشد، میتوان به سازنده این کلاس ارسال کرد. کار وهله سازی وابستگی و واژه کلیدی new به خارج از کلاس استفاده کننده از وابستگی منتقل شده است. بنابراین همانطور که ملاحظه میکنید، این مفاهیم آنچنان پیچیده نبوده و به همین سادگی قابل تعریف و اعمال هستند.
تزریق در خواص عمومی کلاس
Setter Injection و یا تزریق در خواص عمومی یک کلاس، یکی دیگر از روشهای تزریق وابستگیها است (setter در اینجا منظور همان get و set یک خاصیت میباشد).
در حالت تزریق وابستگیها در سازنده کلاس، امکان وهله سازی آن کلاس بدون ارسال وابستگیها به سازنده آن ممکن نیست؛ اما در اینجا خیر و امکان وهله سازی و استفاده از یک کلاس، پیش از اعمال وابستگیها نیز وجود دارد. بنابراین امکان تغییر و تعویض وابستگیها پس از وهله سازی کلاس نیز میسر است.
نمونهای از این روش را در مثال فوق مشاهده میکنید. در این کلاس، وابستگی مورد نیاز از طریق یک خاصیت عمومی دریافت شده است.
تزریق اینترفیسها
تزریق اینترفیسها نیز یکی دیگر از روشهای تزریق وابستگیها است؛ اما آنچنان استفاده گستردهای برخلاف دو روش قبل نیافته است.
در این روش نه از سازنده کلاس استفاده میشود و نه از یک خاصیت عمومی. ابتدا یک اینترفیس که بیانگر ساختار کلاسی که قرار است تزریق شود ایجاد میگردد. سپس این اینترفیس را در کلاس وابستگی مورد نظر پیاده سازی خواهیم کرد. در این اینترفیس نیاز است متد خاصی تعریف شود تا کار تزریق وابستگی را انجام دهد.
یک مثال:
در اینجا یک اینترفیس به نام IDependOnCreditCard تعریف گردیده و متد خاصی را به نام Inject تدارک دیده است که نوعی از کردیت کارد را دریافت میکند.
در ادامه کلاس خریدار، اینترفیس IDependOnCreditCard را پیاده سازی کرده است. به این ترتیب کلاس Injector تنها کافی است بداند تا این متد خاص را باید جهت تنظیم و تزریق وابستگیها فراخوانی نماید. این روش نسبتا شبیه به روش Setter injection است.
این روش بیشتر میتواند جهت فریم ورکهایی که قابلیت یافتن کلیه کلاسهای مشتق شده از IDependOnCreditCard را داشته و سپس میدانند که باید متد Inject آنها را فراخوانی کنند، مناسب است.
نکاتی که باید حین کار با تزریق وابستگیها درنظر داشت
الف) حین استفاده از تزریق وابستگیها، وهله سازی به تاخیر افتاده وابستگیها میسر نیست. برای مثال زمانیکه یک وابستگی قرار است در سازنده کلاسی تزریق شود، وهله سازی آن باید پیش از نیاز واقعی به آن صورت گیرد. البته امکان استفاده از اشیاء Lazy دات نت 4 برای مدیریت این مساله وجود دارد اما در حالت کلی، دیگر همانند قبل و روشهای متداول، وهله سازی تنها زمانیکه نیاز به آن وابستگی خاص باشد، میسر نیست. به همین جهت باید به تعداد وابستگیهایی که قرار است در یک کلاس استفاده شوند نیز جهت کاهش مصرف حافظه دقت داشت.
ب) یکی از مزایای دیگر تزریق وابستگیها، سادهتر شدن نوشتن آزمونهای واحد است. زیرا تهیه Mocks در این حالت کار با اینترفیسها بسیار سادهتر است. اما باید دقت داشت، کلاسی که در سازنده آن حداقل 10 اینترفیس را به عنوان وابستگی دریافت میکند، احتمالا دچار مشکلاتی در طراحی و همچنین مصرف حافظه میباشد.
تزریق وابستگیها یا DI چیست؟
تزریق وابستگیها یکی از انواع IoC بوده که در آن ایجاد و انقیاد (binding) یک وابستگی، در خارج از کلاسی که به آن نیاز دارد صورت میگیرد. روشهای متفاوتی برای ارائه این وابستگی وهله سازی شده در خارج از کلاس به آن وجود دارد که در ادامه مورد بررسی قرار خواهند گرفت.
یک مثال: بسته غذایی را که با خود به سر کار میبرید درنظر بگیرید. تمام اجزای مورد نیاز تشکیل دهنده یک بسته غذا عموما داخل آن قرار گرفته و حمل میشوند. حالت عکس آن زمانی است که در محل کار به شما غذا میدهند. این دقیقا همان حالتی است که تزریق وابستگیها کار میکند؛ یک سری سرویسهای خارجی، نیازهای کلاس جاری را برآورده میسازند.
در تصویر فوق یک طراحی مبتنی بر معکوس سازی کنترلها را مشاهده میکنید. وابستگیهای یک کلاس توسط اینترفیسی مشخص شده و سپس کلاسی وجود دارد که این وابستگی را پیاده سازی کرده است.
همچنین در این تصویر یک خط منقطع از کلاس MyClass به کلاس Dependency رسم شده است. این خط، مربوط به حالتی است که خود کلاس، مستقیما کار وهله سازی وابستگی مورد نیاز خود را انجام دهد؛ هر چند اینترفیسی نیز در این بین تعریف شده باشد. بنابراین اگر در بین کدهای این کلاس، چنین کدی مشاهده شد:
IDependency dependency= new Dependency();
در اینجا یک کلاس دیگر به نام Injector اضافه شده است که قابلیت تزریق وابستگیها را به کلاس نیازمند آن به روشهای مختلفی دارا است. کار کلاس Injector، وهله سازی MyClass و همچنین وابستگیهای آن میباشد؛ سپس وابستگی را دراختیار MyClass قرار میدهد.
تزریق وابستگیها در سازنده کلاس
یکی از انواع روشهای تزریق وابستگیها، Constructor Injection و یا تزریق وابستگیها در سازنده کلاس میباشد که متداولترین نوع آنها نیز بهشمار میرود. در این حالت، وابستگی پس از وهله سازی، از طریق پارامترهای سازنده یک کلاس، در اختیار آن قرار میگیرند.
یک مثال:
public class Shopper { private readonly ICreditCard _creditCard; public Shopper(ICreditCard creditCard) { _creditCard = creditCard; } }
ICreditCard creditCard = new MasterCard(); Shopper shopper = new Shopper(creditCard);
تزریق در خواص عمومی کلاس
Setter Injection و یا تزریق در خواص عمومی یک کلاس، یکی دیگر از روشهای تزریق وابستگیها است (setter در اینجا منظور همان get و set یک خاصیت میباشد).
در حالت تزریق وابستگیها در سازنده کلاس، امکان وهله سازی آن کلاس بدون ارسال وابستگیها به سازنده آن ممکن نیست؛ اما در اینجا خیر و امکان وهله سازی و استفاده از یک کلاس، پیش از اعمال وابستگیها نیز وجود دارد. بنابراین امکان تغییر و تعویض وابستگیها پس از وهله سازی کلاس نیز میسر است.
public class Shopper { public ICreditCard CreditCard { get; set; } } ICreditCard creditCard = new MasterCard(); Shopper shopper = new Shopper(); shopper.CreditCard = creditCard;
تزریق اینترفیسها
تزریق اینترفیسها نیز یکی دیگر از روشهای تزریق وابستگیها است؛ اما آنچنان استفاده گستردهای برخلاف دو روش قبل نیافته است.
در این روش نه از سازنده کلاس استفاده میشود و نه از یک خاصیت عمومی. ابتدا یک اینترفیس که بیانگر ساختار کلاسی که قرار است تزریق شود ایجاد میگردد. سپس این اینترفیس را در کلاس وابستگی مورد نظر پیاده سازی خواهیم کرد. در این اینترفیس نیاز است متد خاصی تعریف شود تا کار تزریق وابستگی را انجام دهد.
یک مثال:
public interface IDependOnCreditCard { void Inject(ICreditCard creditCard); } public class Shopper : IDependOnCreditCard { private ICreditCard creditCard; public void Inject(ICreditCard creditCard) { this.creditCard = creditCard; } } ICreditCard creditCard = new MasterCard(); Shopper shopper = new Shopper(); ((IDependOnCreditCard)shopper).Inject(creditCard);
در ادامه کلاس خریدار، اینترفیس IDependOnCreditCard را پیاده سازی کرده است. به این ترتیب کلاس Injector تنها کافی است بداند تا این متد خاص را باید جهت تنظیم و تزریق وابستگیها فراخوانی نماید. این روش نسبتا شبیه به روش Setter injection است.
این روش بیشتر میتواند جهت فریم ورکهایی که قابلیت یافتن کلیه کلاسهای مشتق شده از IDependOnCreditCard را داشته و سپس میدانند که باید متد Inject آنها را فراخوانی کنند، مناسب است.
نکاتی که باید حین کار با تزریق وابستگیها درنظر داشت
الف) حین استفاده از تزریق وابستگیها، وهله سازی به تاخیر افتاده وابستگیها میسر نیست. برای مثال زمانیکه یک وابستگی قرار است در سازنده کلاسی تزریق شود، وهله سازی آن باید پیش از نیاز واقعی به آن صورت گیرد. البته امکان استفاده از اشیاء Lazy دات نت 4 برای مدیریت این مساله وجود دارد اما در حالت کلی، دیگر همانند قبل و روشهای متداول، وهله سازی تنها زمانیکه نیاز به آن وابستگی خاص باشد، میسر نیست. به همین جهت باید به تعداد وابستگیهایی که قرار است در یک کلاس استفاده شوند نیز جهت کاهش مصرف حافظه دقت داشت.
ب) یکی از مزایای دیگر تزریق وابستگیها، سادهتر شدن نوشتن آزمونهای واحد است. زیرا تهیه Mocks در این حالت کار با اینترفیسها بسیار سادهتر است. اما باید دقت داشت، کلاسی که در سازنده آن حداقل 10 اینترفیس را به عنوان وابستگی دریافت میکند، احتمالا دچار مشکلاتی در طراحی و همچنین مصرف حافظه میباشد.
نظرات مطالب
ساخت دیتابیس sqlite با EF6 Code First
سلام مجدد
کد xml فایل Package
من از دات نت Core استفاده نمیکنم.
من مطابق زیر عمل کردم ولی بازم همان خطا را میدهد.
the underlying provider failed to open
نمیدونم چرا تگ Connection-string را نمیشناسه.
دقیقا در پروژه شما اگر تگ Connection-string را برداریم با چنین خطایی روبرو میشویم.
من پروژه تستی خودم را اینجا آپلود کردم.
کد XML فایل پروژه
<?xml version="1.0" encoding="utf-8"?> <!-- For more information on how to configure your ASP.NET application, please visit http://go.microsoft.com/fwlink/?LinkId=301880 --> <configuration> <configSections> <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" /> <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 --> </configSections> <appSettings> <add key="webpages:Version" value="3.0.0.0" /> <add key="webpages:Enabled" value="false" /> <add key="ClientValidationEnabled" value="true" /> <add key="UnobtrusiveJavaScriptEnabled" value="true" /> </appSettings> <connectionStrings> <add name="constr" connectionString="data source=.\phonebook.sqlite;foreign keys=true" providerName="System.Data.SQLite" /> </connectionStrings> <system.web> <compilation debug="true" targetFramework="4.5" /> <httpRuntime targetFramework="4.5" /> </system.web> <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" /> <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" /> </dependentAssembly> <dependentAssembly> <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" /> <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" /> </dependentAssembly> <dependentAssembly> <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" /> <bindingRedirect oldVersion="1.0.0.0-5.2.3.0" newVersion="5.2.3.0" /> </dependentAssembly> </assemblyBinding> </runtime> <system.codedom> <compilers> <compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:6 /nowarn:1659;1699;1701" /> <compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:14 /nowarn:41008 /define:_MYTYPE=\"Web\" /optionInfer+" /> </compilers> </system.codedom> <entityFramework> <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework"> <parameters> <parameter value="v13.0" /> </parameters> </defaultConnectionFactory> <!--<providers> <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" /> </providers>--> <providers> <provider invariantName="System.Data.SQLite" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6" /> <provider invariantName="System.Data.SQLite.EF6" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6" /> <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" /> </providers> </entityFramework> <system.data> <DbProviderFactories> <remove invariant="System.Data.SQLite.EF6" /> <add name="SQLite Data Provider (Entity Framework 6)" invariant="System.Data.SQLite.EF6" description=".NET Framework Data Provider for SQLite (Entity Framework 6)" type="System.Data.SQLite.EF6.SQLiteProviderFactory, System.Data.SQLite.EF6" /> <remove invariant="System.Data.SQLite" /> <add name="SQLite Data Provider" invariant="System.Data.SQLite" description=".NET Framework Data Provider for SQLite" type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite" /> </DbProviderFactories> </system.data> </configuration>
<?xml version="1.0" encoding="utf-8"?> <packages> <package id="bootstrap" version="3.0.0" targetFramework="net45" /> <package id="EntityFramework" version="6.1.3" targetFramework="net45" /> <package id="jQuery" version="1.10.2" targetFramework="net45" /> <package id="Microsoft.AspNet.Mvc" version="5.2.3" targetFramework="net45" /> <package id="Microsoft.AspNet.Razor" version="3.2.3" targetFramework="net45" /> <package id="Microsoft.AspNet.WebPages" version="3.2.3" targetFramework="net45" /> <package id="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" version="1.0.0" targetFramework="net45" /> <package id="Microsoft.Net.Compilers" version="1.0.0" targetFramework="net45" developmentDependency="true" /> <package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net45" /> <package id="Modernizr" version="2.6.2" targetFramework="net45" /> <package id="SQLite.CodeFirst" version="1.3.0.17" targetFramework="net45" /> <package id="System.Data.SQLite" version="1.0.105.0" targetFramework="net45" /> <package id="System.Data.SQLite.Core" version="1.0.105.0" targetFramework="net45" /> <package id="System.Data.SQLite.EF6" version="1.0.105.0" targetFramework="net45" /> <package id="System.Data.SQLite.Linq" version="1.0.105.0" targetFramework="net45" /> </packages>
مابقی همون کلاسها و کدهای مثال آزمایشی شماست.
من انتظار دارم در لحظه اول در نبود Database.sqlte آن را ایجاد کند. ( مانند مثال شما )
گواهینامه SSL دارای انواع مختلفی است، که هر نوع آن تامین کننده نیاز خاصی میباشد و از اعتبار و قیمت متفاوتی برخوردار است و علاوه بر تامین امنیت میتواند اعتبار یک سازمان را نمایش دهد. به منظور انتخاب بهترین نوع گواهینامه SSL و صرف مناسبترین هزینه به منظور برآورده نمودن نیاز و کارایی مطلوب، لازم است ابتدا تعریفی از آنها داشته باشیم ...
اشتراکها
ده نکته در مورد Patentها
یک . پتنت چیست؟
دو . ایدهها به پتنت تبدیل نمیشوند.
سه پتنتها کشورگرا هستند.
چهار. انواع پتنت
پنج. پتنتی که اول ثبت گردد برنده است نه ابداع شود.
شش. دریافت پتنت زمان بر است.
هفت. پتنت باید در دنیا منحصر به فرد باشد.
هشت . دریافت پتنت هزینه دارد.
نه. قوانین پتنت دائما در حال تغییر است.
ده. به ترول پتنتها دقت کنید.
برای درک عملکرد قطعه کد نوشته شده و ماهیت پویای اشیای جاوا اسکریپتی، این مطلب را مطالعه کنید: «برنامه نویسی پیشرفته JavaScript - قسمت 3 - انواع ارجاعی و نحوهی ایجاد اشیاء»