برای انتقال جداول احراز هویت (Identity) از SQL Server به بانک اطلاعاتی
MongoDB و نحوه استفاده از آن در ASP.Net Core از سورس نمونه در لینک بالا استفاده کنید.
همچنین میتوانید از پکیج AspNetCore.Identity.Mongo استفاده کنید.
شما کدامیک از بانک های nosql سندگرا را ترجیح می دهید؟
MongoDb یکی از بهترین noSQL هایی هست که تا حالا کار کردم و مزیت آن نسبت به بقیه رایگان بودن و وجود منابع آموزشی و رفع اشکال زیاد آن است.
البته بقیه هم خوب هستند ولی MongoDb آموزشهای زیادی هم داره که همه کاربران بدون هیچ زحمت و هزینه میتوانند از آن استفاده کنند.
وجود Driverهای مناسب و استفاده آسان آن در هر زبانی هم یکی دیگه از دلایل استفاده بنده از آن شده است مخصوصا در asp.net mvc , php براحتی میتوان از آن استفاده کرد.
ثبت پیاده سازیهای متعدد یک اینترفیس در سیستم تزریق وابستگیهای NET Core.
داشتن چندین پیاده سازی از یک اینترفیس، شاید یکی از اهداف اصلی وجود آنها باشد. برای نمونه قرار داد ارسال پیامی را در برنامه، مانند IMessageService به صورت زیر طراحی و سپس بر اساس آن، دو پیاده سازی ارسال پیامها را از طریق ایمیل و SMS، اضافه میکنیم:
namespace CoreIocServices { public interface IMessageService { void Send(string message); } public class EmailService : IMessageService { public void Send(string message) { // ... } } public class SmsService : IMessageService { public void Send(string message) { //todo: ... } } }
namespace CoreIocSample02 { public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddTransient<IMessageService, EmailService>(); services.AddTransient<IMessageService, SmsService>(); }
using CoreIocServices; using Microsoft.AspNetCore.Mvc; namespace CoreIocSample02.Controllers { public class MessagesController : Controller { private readonly IMessageService _emailService; private readonly IMessageService _smsService; public MessagesController(IMessageService emailService, IMessageService smsService) { _emailService = emailService; _smsService = smsService; } } }
همانطور که مشاهده میکنید، هر دو پارامتر، با وهلهای از آخرین سرویس معرفی شدهی از نوع IMessageService مقدار دهی شدهاند؛ یعنی SmsService در اینجا. در ادامه روشهای مختلفی را برای رفع این مشکل بررسی میکنیم.
روش اول: سیستم تزریق وابستگیهای NET Core. از سازندههای IEnumerable پشتیبانی میکند
برای مدیریت دریافت سرویسهایی که از یک اینترفیس مشتق شدهاند، خود NET Core. بدون نیاز به تنظیمات اضافهتری، روش تزریق IEnumerableها را در سازندههای کلاسها پشتیبانی میکند:
using System.Collections.Generic; using CoreIocServices; using Microsoft.AspNetCore.Mvc; namespace CoreIocSample02.Controllers { public class MessagesController : Controller { private readonly IEnumerable<IMessageService> _messageServices; public MessagesController(IEnumerable<IMessageService> messageServices) { _messageServices = messageServices; }
به این ترتیب لیست وهلههای تمام سرویسهایی از نوع IMessageService در اختیار ما قرار گرفتهاست و برای اهدافی مانند پیاده سازی الگوهایی در ردهی chain of responsibility و یا الگوی استراتژی، مفید است. در این حالت اگر نیاز به سرویس از نوع خاصی وجود داشت، میتوان از روش زیر استفاده کرد:
var emailService = _messageServices.OfType<EmailService>().First();
var messageServices = serviceProvider.GetServices<IMessageService>();
روش دوم: دریافت شرطی وهلههای مورد نیاز با «دخالت در مراحل وهله سازی اشیاء توسط IoC Container»
روش «دخالت در مراحل وهله سازی اشیاء توسط IoC Container» را در قسمت قبل بررسی کردیم. یکی دیگر از مثالهایی را که در این مورد میتوان ارائه داد، شرطی کردن بازگشت وهلهها است که برای سناریوی مطلب جاری بسیار مفید است:
الف) برای شرطی کردن بازگشت وهلهها، بهتر است این شرط را بجای رشتهها و یا اعدادی خاص، بر اساس یک enum مشخص انجام دهیم:
namespace CoreIocServices { public enum MessageServiceType { EmailService, SmsService }
ب) سپس هر دو سرویس مشتق شدهی از یک اینترفیس را به صورت معمولی ثبت میکنیم:
namespace CoreIocSample02 { public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddTransient<EmailService>(); services.AddTransient<SmsService>();
ج) اکنون میتوان مرحلهی شرطی کردن بازگشت این وهلهها را به صورت زیر، با دخالت در مراحل وهله سازی اشیاء، پیاده سازی کرد:
namespace CoreIocSample02 { public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddTransient<EmailService>(); services.AddTransient<SmsService>(); services.AddTransient<Func<MessageServiceType, IMessageService>>(serviceProvider => key => { switch (key) { case MessageServiceType.EmailService: return serviceProvider.GetRequiredService<EmailService>(); case MessageServiceType.SmsService: return serviceProvider.GetRequiredService<SmsService>(); default: throw new NotImplementedException($"Service of type {key} is not implemented."); } });
د) مرحلهی آخر کار، روش استفادهی از این امضایء ویژهی Lazy load شدهاست:
namespace CoreIocSample02.Controllers { public class MessagesController : Controller { private readonly Func<MessageServiceType, IMessageService> _messageServiceResolver; public MessagesController(Func<MessageServiceType, IMessageService> messageServiceResolver) { _messageServiceResolver = messageServiceResolver; }
public IActionResult Index() { var emailService = _messageServiceResolver(MessageServiceType.EmailService); //use emailService ... return View(); }
کدهای کامل این قسمت را از اینجا میتوانید دریافت کنید: CoreDependencyInjectionSamples-07.zip
ایجاد یک برنامهی خالی React برای آزمایش توابع Redux
در اینجا برای بررسی توابع Redux، یک پروژهی جدید React را ایجاد میکنیم:
> npm i -g create-react-app > create-react-app state-management-redux-mobx > cd state-management-redux-mobx > npm start
> npm install --save redux
معرفی سریع توابع Redux
Redux، کتابخانهی کوچکی است و تنها از 5 تابع تشکیل شدهاست:
applyMiddleware: function() bindActionCreators: function() combineReducers: function() compose: function() createStore: function()
بررسی تابع compose با یک مثال
پس از ایجاد پروژهی React و افزودن کتابخانهی Redux به آن، به فایل src\index.js این پروژه مراجعه کرده و محتویات آنرا با قطعه کد ذیل، تعویض میکنیم:
import { compose } from "redux"; const makeLouder = text => text.toUpperCase(); const repeatThreeTimes = text => text.repeat(3); const embolden = text => text.bold(); const makeLouderAndRepeatThreeTimesAndEmbolden = compose( embolden, repeatThreeTimes, makeLouder ); console.log(makeLouderAndRepeatThreeTimesAndEmbolden("Hello"));
- سپس سه تابع ساده را برای ضخیم کردن، تکرار و با حروف بزرگ نمایش دادن یک متن ورودی، تعریف کردهایم.
- اکنون با استفاده از متد compose کتابخانهی redux، این سه متد را به صورت ترکیبی، بر روی متن ورودی Hello، اعمال کردهایم.
- در آخر اگر برای مشاهدهی نتیجهی اجرای console.log بر روی آن، به کنسول توسعه دهندگان مرورگر مراجعه کنیم، به خروجی زیر خواهیم رسید:
<b>HELLOHELLOHELLO</b>
بررسی تابع createStore با یک مثال
Store در Redux، جائی است که در آن state برنامه ذخیره میشود. تابع createStore که کار ایجاد store را انجام میدهد، یک پارامتر را دریافت میکند و آنهم تابع reducer است که در قسمت قبل معرفی شد و در سادهترین حالت آن، به نحو زیر با یک متد خالی، قابل فراخوانی است:
import { createStore } from "redux"; createStore(() => {});
import { createStore } from "redux"; const reducer = (state, action) => { return state; }; const store = createStore(reducer); console.log(store);
در شیء store، چهار متد dispatch, subscribe, getState, replaceReducer مشخص هستند:
- کارکرد متد replaceReducer مشخص است؛ یک reducer جدید را به آن میدهیم و reducer قبلی را جایگزین میکند.
- متد dispatch آن مرتبط است به مبحث dispatch actions که در قسمت قبل به آن پرداختیم. هدف آن تغییر state، بر اساس یک action رسیدهاست.
- متد getState، وضعیت فعلی state را باز میگرداند.
- متد subscribe با هر تغییری در state، سبب بروز رخدادی میشود. یکی از کاربردهای آن میتواند به روز رسانی UI، بر اساس تغییرات state باشد. برای مثال کتابخانهی دیگری به نام react redux، دقیقا همین کار را به کمک متد subscribe، انجام میدهد. در این قسمت، هدف ما بررسی پشت صحنهی کتابخانههایی مانند react redux است که چه متدهایی را محصور کردهاند و دقیقا چگونه کار میکنند.
در مثال زیر، مقدار ابتدایی پارامتر state متد reducer را به یک شیء که دارای خاصیت value و مقدار 1 است، تنظیم کردهایم:
import { createStore } from "redux"; const reducer = (state = { value: 1 }, action) => { return state; }; const store = createStore(reducer); console.log(store.getState());
در کامپوننتهای React، این نوع خواص به صورت props ارسال میشوند. کل state در Redux ذخیره شده و سپس قابل دسترسی و خواندن خواهد شد.
بررسی متد dispatch یک store با مثال
در اینجا مثالی را از کاربرد متد dispatch ملاحظه میکنید که یک شیء را میپذیرد:
import { compose, createStore } from "redux"; const reducer = (state = { value: 1 }, action) => { console.log("Something happened!", action); return state; }; const store = createStore(reducer); console.log(store.getState()); store.dispatch({ type: "ADD" });
فرمت شیءای که به متد dispatch ارسال میشود، حتما باید به همراه خاصیت type باشد؛ در غیر اینصورت با صدور استثنائی، این نکته را گوشزد میکند. مقدار آن نیز یک رشتهاست که بیانگر وقوع رخدادی در برنامه میباشد؛ برای مثال کاربر درخواست دریافت اطلاعاتی را کردهاست و یا کاربر از سیستم خارج شدهاست و امثال آن.
خروجی قطعه کد فوق، به صورت زیر است:
با اجرای برنامه، یک رخداد درونی از نوع redux/INITo.2.g.b.y.i@@ صادر شدهاست که هدف آن آغاز و مقدار دهی اولیهی store است. پس از آن زمانیکه متد store.dispatch فراخوانی شدهاست، مجددا console.log داخل متد reducer فراخوانی شدهاست که اینبار به همراه type ای است که ما مشخص کردهایم.
در حالت کلی، اینکه شیء ارسالی توسط dispatch را چگونه طراحی میکنید، اختیاری است؛ اما الگوی پیشنهادی در این زمینه، redux standard actions نام دارد و به صورت زیر است که هدف از آن، یکدست شدن طراحی و پیاده سازی برنامه است:
store.dispatch({ type: "ADD", payload: { amount: 2 }, meta: {} });
- سپس به خاصیت payload، تمام دادههای مرتبط با آن اکشن، مانند نتیجهی بازگشتی از یک API، به صورت یک شیء، انتساب داده میشود.
- خاصیت meta، مرتبط با متادیتا و اطلاعات اضافی است که عموما استفاده نمیشود.
اکنون که طراحی شیء ارسالی به پارامتر action متد reducer مشخص شد، میتوان بر اساس خاصیت type آن، یک switch را طراحی کرد و نسبت به نوعهای مختلف رسیده، واکنش نشان داد:
import { createStore } from "redux"; const reducer = (state = { value: 1 }, action) => { console.log("Something happened!", action); if (action.type === "ADD") { const value = state.value; const amount = action.payload.amount; state.value = value + amount; } return state; }; const store = createStore(reducer); const firstState = store.getState(); console.log(firstState); store.dispatch({ type: "ADD", payload: { amount: 2 }, meta: {} }); const secondState = store.getState(); console.log(secondState); console.log("secondState === firstState", secondState === firstState);
یک روش حل این مشکل، حذف سطر state.value = value + amount و جایگزینی آن با یک return است که شیء state جدیدی را بازگشت میدهد:
return { value: value + amount };
بررسی متد subscribe یک store با مثال
در ادامه به store همان مثال فوق، متد subscribe را نیز اضافه میکنیم و سپس دوبار، کار store.dispatch را انجام خواهیم داد:
const store = createStore(reducer); const unsubscribe = store.subscribe(() => console.log(store.getState())); store.dispatch({ type: "ADD", payload: { amount: 2 }, meta: {} }); store.dispatch({ type: "ADD", payload: { amount: 2 }, meta: {} }); unsubscribe();
- خروجی مستقیم متد store.subscribe نیز یک متد است که unsubscribe نام دارد و میتوان در پایان کار، برای جلوگیری از نشتیهای حافظه، آنرا فراخوانی کرد.
خروجی حاصل از console.log منتسب به متد store.subscribe، با دوبار فراخوانی متد store.dispatch پس از آن، به صورت زیر است:
{value: 3} {value: 5}
بررسی تابع combineReducers با یک مثال
اگر قرار باشد در متد reducer، صدها if action.type را تعریف کرد ... پس از مدتی از کنترل خارج میشود و غیرقابل نگهداری خواهد شد. تابع combineReducers به همین جهت طراحی شدهاست تا چندین متد مجزای reducer را با هم ترکیب کند. بنابراین میتوان در برنامه صدها متد کوچک reducer را که قابلیت توسعه و نگهداری بالایی را دارند، پیاده سازی کرد و سپس با استفاده از تابع combineReducers، آنها را یکی کرده و به متد createStore ارسال کرد. نکتهی مهم اینجا است که هرچند اینبار میتوان تعداد زیادی reducer را طراحی کرد، اما توسط تابع combineReducers، مقدار action ارسالی، از تمام این reducerها عبور داده خواهد شد. به این ترتیب اگر نیاز بود میتوان به یک action، در چندین متد مختلف reducer گوش فرا داد و بر اساس آن تصمیم گیری کرد. بنابراین بهتر است هر reducer تعریف شده در صورتیکه action.type آن با action رسیده تطابق نداشته باشد، همان state قبلی را بازگشت دهد تا بتوان زنجیرهی reducerها را تشکیل داد و بهتر مدیریت کرد.
برای نمونه اگر متد reducer فعلی را به calculatorReducer تغییر نام دهیم، روش معرفی آن توسط متد combineReducers به متد createStore به صورت زیر است:
import { combineReducers, createStore } from "redux"; // ... const calculatorReducer = (state = { value: 1 }, action) => { // ... }; const store = createStore( combineReducers({ calculator: calculatorReducer }) );
بررسی تابع bindActionCreators با یک مثال
فرض کنید میخواهیم متد dispatch را چندین بار فراخوانی کنیم:
store.dispatch({ type: "ADD", payload: { amount: 2 }, meta: {} }); store.dispatch({ type: "ADD", payload: { amount: 2 }, meta: {} });
const createAddAction = amount => { return { type: "ADD", payload: { amount // = amount: amount }, meta: {} }; };
store.dispatch(createAddAction(2)); store.dispatch(createAddAction(2));
import { bindActionCreators, combineReducers, compose, createStore } from "redux"; // ... const dispatchAdd = bindActionCreators(createAddAction, store.dispatch); dispatchAdd(2); dispatchAdd(2);
میانافزارها (Middlewares) در Redux
پس از اینکه یک اکشن، به سمت reducer ارسال شد و پیش از رسیدن آن به reducer، میتوان کدهای دیگری را نیز اجرا کرد. برای مثال چون این توابع خالص هستند، نمیتوان اعمالی را داخل آنها اجرا کرد که به همراه اثرات جانبی مانند کار با یک API خارجی باشند. با استفاده از میانافزارها در این بین میتوان کدهایی را که با دنیای خارج تعامل دارند نیز اجرا کرد.
یک میانافزار در Redux، همانند سایر قسمتهای آن، تنها یک تابع سادهی جاوا اسکریپتی است:
const logger = ({ getState }) => { return next => action => { console.log( 'MIDDLEWARE', getState(), action ); const value = next(action); console.log({value}); return value; } }
در پایان کار میانافزار باید متد next آنرا فراخوانی کرد تا بتوان میانافزارهای متعددی را زنجیروار اجرا کرد.
در آخر برای معرفی آن به یک store میتوان از تابع applyMiddleware استفاده کرد:
import { applyMiddleware, bindActionCreators, combineReducers, compose, createStore } from "redux"; // ... const store = createStore( combineReducers({ calculator: calculatorReducer }), applyMiddleware(logger) );
کدهای کامل این قسمت را از اینجا میتوانید دریافت کنید: state-management-redux-mobx-part02.zip
در این بخش تعاریف، خصوصیات، مزایا و معایب مرتبط با این نوع سیستمها بررسی میشوند.
تعریف سیستمهای توزیع شده
تعاریف مختلفی توسط اشخاص و گروههای مختلف، از سیستمهای توزیع شده وجود دارد. در اینجا سعی شده که اکثر این تعاریف معرفی شوند؛ بگونهای که با ارائه نکات کلیدی این تعاریف به درک بهتری از خصوصیات سیستمهای توزیع شده برسیم.
تعاریف سیستمهای توزیع شده
تعریف اول: سیستمهای توزیع شده از مجموعهای از سخت افزارها و نرم افزارها که برای رسیدن به یک هدف واحد از طریق شبکه با یکدیگر در ارتباطند تشکیل شده.
تعریف دوم: یک مجموعه از Computerهای مستقل که از نظر کاربر یک Computer و یک سیستم واحد و منسجمند.
تعریف سوم: سیستمهای توزیع شده در واقع هنری هستند که بوسیله آنها میتوانید مشکلاتی را که در یک کامپیوتر وجود دارند، با استفاده از چند کامپیوتر رفع کنید و معمولا به این دلیل انتخاب میشوند که این مشکلات توسط یک کامپیوتر رفع نمیشوند.
تعریف چهارم: زیر سیستمهایی که بصورت همزمان میتوانند پردازش یک سیستم بزرگ را انجام دهند؛ البته همزمانی که در آن مانند سیستمهای Parallel از یک حافظه مشترک استفاده نشود.
تعریف پنجم: مجموعه ای از پردازشهای مرتبط به هم، بصورتی که هر پردازش از حافظه داخلی مرتبط با خودش استفاده کند و تمام این پردازشها از طریق Message passing در سطح شبکه با یکدیگر در ارتباطند.
تعریف ششم: تقسیم بندی وظایف یک سیستم بزرگ به زیرسیستمهایی که در سخت افزارهای مجزا اجرا میشوند و کاربر هیچ تصوری از وجود این زیر سیستمها ندارد.
در تعاریف فوق نکات کلیدی وجود دارد که میتوانند خصوصیات سیستمهای توزیع شده نیز باشند و با در نظر گرفتن آنها میتوانید به درک بهتری از سیستمهای توزیع شده برسید.
نکات کلیدی یا خصوصیات سیستمهای توزیع شده
1- داشتن یک هدف واحد در سیستمهای توزیع شده، زیر سیستمهایی که از نظر کاربر یک سیستم واحد و متمرکزند: این یکی از خصوصیات و نکات کلیدی سیستمهای توزیع شدهاست که تمام اجزاء و زیرسیستمها در راه رسیدن به یک هدف واحد با یکدیگر در ارتباط اند. ارتباطی که باعث همکاری آنها میشود و همکاری که باید بصورت کامل از دید کاربر مخفی بماند (داشتن یک هدف واحد یکی از تفاوتهای سیستمهای توزیع شده با Cloud distributed systemها میباشد. چون در Cloud distributed systemها لزوما تمام اجزا برای رسیدن به یک هدف مشترک با یکدیگر کار نمیکنند).
2- کامپیوترهای مستقل، حافظههای داخلی جداگانه، عدم وجود حافظه مشترک: یکی از مهمترین تفاوتهای سیستمهای توزیع شده با سیستمهای Parallel، عدم وجود حافظه مشترک بین پردازشهای جداگانه است. یعنی در این نوع سیستمها، هر زیرسیستم در یک کامپیوتر مجزا که حافظه داخلی خودش را دارد اجرا میشود.
3- تقسیم بندی وظایف: که یکی از نکات کلیدی این نوع سیستمها میباشد. تقسیم بندی میتواند به هر دلیلی که شما درنظر میگیرید صورت بپذیرد. دلایلی برای بالا بردن کارآیی، امنیت، در دسترس بودن، یا حتی دلایل مربوط به Business سیستم شما.
4- ارتباط از طریق شبکه، ارتباطی که از طریق Message passing صورت میپذیرد: این خصوصیت در واقع پایه تمام تعاریف سیستمهای توزیع شدهاست. در سیستمهای توزیع شده همه چیز از ارتباطهایی که از طریق شبکه صورت میپذیرد، شروع میشود .
مزایای استفاده از سیستمهای توزیع شده
1- کارآیی بسیار بالاتر: بدلیل همزمان اجرا شدن کارها در سخت افزارهای مختلف، کارآیی این نوع سیستمها بسیار بیشتر از سیستمهای متمرکز است.
2- قابلیت همکاری بیشتر: بدلیل اینکه این سیستمها ذاتا توزیع شده هستند، با کمترین هزینه و پیچیدگی میتوانند با سایر سیستمها همکاری لازم را داشته باشند.
3- قابلیت در دسترس بودن و اطمینان بیشتر: در این سیستمها با روشهای مختلفی مانند replication، به راحتی میتوان این دو قابلیت را در بالاترین سطح قرار داد.
4- مقیاس پذیری: مقیاس پذیری در این سیستمها با قرار دادن کامپوننتهایی که قابلیت استفاده مجدد بالایی را دارند در سرورهای جدید به راحتی و بدون از دسترس خارج شدن سیستم صورت میپذیرد.
5- قابلیت گسترش: برای گسترش سیستم و اضافه کردن نیازمندیهای جدید در این سیستمها، به راحتی میتوان کامپوننتها و زیرسیستمهای جدیدی را پیاده سازی کرد و بدون از دسترس خارج شدن سیستم و به گونهای که به راحتی با سایر قسمتهای موجود در ارتباط باشند، آنها را به سیستم اضافه کرد.
6- بهره وری بالاتر و زمان توسعه کمتر: بدلیل تقسیم بندی قسمتهای بزرگ به قسمتهای کوچکتر، تیمهای مختلف میتوانند بصورت همزمان قسمتهای کوچک را توسعه دهند.
7- قابلیت استفاده مجدد بسیار بالا: در این نوع سیستمها به راحتی میتوانید از یک زیرسیستم یا کامپوننت خاص که یکبار پیاده سازی شده و در سخت افزار جداگانهای اجرا شده، در تمام Applicationها استفاده کنید.
8- کاهش هزینه: در مواردی مانند قابلیت استفادهی مجدد بالا و توسعه پذیری سیستم، میتوانند باعث کاهش هزینهها شوند (در صورت انتخاب نادرست این نوع سیستم، این مزیت میتواند تبدیل به یکی از معایب سیستم شود).
9- امنیت: بدلیل اینکه هر زیرسیستم در یک سخت افزار جداگانه اجرا میشود که مکان آن از قبل مشخص نیست و همچنین تقسیم بندی قسمتهایی که نیاز به امنیت بالایی دارند، میتواند بر اساس نیاز و در سخت افزارهایی که حتی به اینترنت هم متصل نیستند، صورت بپذیرد. این نوع سیستم میتواند از امنیت بالایی برخوردار باشد (البته در صورت طراحی نادرست، امنیت میتواند بعنوان یکی از معایب این نوع سیستمها نیز مطرح شود).
معایب استفاده از سیستمهای توزیع شده
1- پیچیدگی در انتخاب، طراحی و پیاده سازی سیستمهای توزیع شده: یکی از اصلیترین معایب سیستمهای توزیع شده، پیچیدگیهایی است که در انتخاب، طراحی و پیاده سازی آنها وجود دارد. به دلیل پیچیدگیهایی که در هریک از این قسمتها وجود دارد، در صورت اتخاذ تصمیمات نادرست، در هر یک از این قسمتها اکثر مزایای آنها میتوانند تبدیل به معایب این نوع سیستمها شوند.
2- بالا رفتن زمان طراحی و پیاده سازی: بدلیل بوجود آمدن مفاهیم جدید و پیچیدگی که در این نوع سیستم وجود دارد و همچنین بدلیل کم بودن نیروی متخصص در این نوع سیستم، زمان توسعه آنها میتواند بیشتر از سیستمهای متمرکز باشد.
3- هزینه طراحی و پیاده سازی بیشتر: دلایل 1 و 2 میتوانند باعث بالا رفتن هزینههای طراحی و پیاده سازی این نوع سیستمها شوند.
4- هزینههای بیشتر مرتبط با شبکه: در این نوع سیستمها بدلیل استفاده بیشتر از منابع، مانند سخت افزارها و ابزارهای مرتبط با شبکه، هزینههای مرتبط با استفاده از منابع، مانند برق و شبکه بیشتر از سیستمهای متمرکز است.
5- کاهش امنیت: توزیع نادرست منابع سیستم در سخت افزارهای متفاوت و مدیریت نادرست این منابع باعث کاهش امنیت این نوع سیستمها میشود.
6- مدیریت دشوارتر: بدلیل اینکه سیستمهای توزیع شده از زیرسیستمهای زیادی تشکیل شده و هر یک از این زیر سیستمها در سخت افزارهای متفاوتی اجرا شدهاند، مدیریت و سازماندهی این نوع سیستمها دشوارتر از سیستمهای متمرکز است.
بدلیل اینکه همیشه قسمتهای مرتبط با پیاده سازی این نوع سیستمها از تعاریف آنها جذابتر است، سعی کردهام در این بخش و بخش بعد که اهداف و اصطلاحات مرتبط با سیستمهای توزیع شده را بررسی میکند، کمتر وارد جزئیات مفاهیم شوم. در صورت نیاز به توضیح بیشتر در مورد قسمت خاصی از این مفاهیم، در قسمت نظرات آنها را مطرح کنید.
کار با RavenDB از طریق REST API آن
با تشکر فراوان از شما
برای کار با حجم زیاده داده آیا حالت نصب embedded را پیشنهاد میکنید؟
بین RavenDB و MongoDB در پلت فورم Asp.net MVC 4 کدامیک را پیشنهاد میکنید؟
اگه قبلا با EF/EFCore کار میکردین و الان میخواین از MongoDb استفاده کنین و میخواین از دانش قبلیتون + مزایای Entity Framework استفاده کنین بهترین گزینه MongoFramework هست
قبلا یه پروایدر مخصوص MongoDb برای EFCore ساخته شد که متاسفانه زیاد توسعه داده نشد (مخزن گیتهابش) و حتی به انتشار نسخه Stable هم نرسید
از بین کتابخونه هایی که تجربه مشابه Entity Framework رو برای MongoDb فراهم میکنن یکی MongoFramework هست و دیگری MongoDbContext (که البته به پای اون یکی نمیرسه)
یه MongoDbGenericRepository هم هست که صرفا یه Wrapper رو MongoDb هست و سعی کرده یه پیاده سازی از Repository ارائه بده ولی امکانات EF و DbContext طوری نداره
خلاصه اینکه من همه معروفاشونو بررسی کردم و بهترینشون همین MongoFramework هست که البته همه امکانات EF رو نداره ولی بازم امکانات خوبی داره که توی گیتهابش توضیح داده و پیشنهاد میکنم یه نگاه به صفحه گیتهابش بندازین