This is a viewer only at the moment see the article on how this works.
To update the preview hit Ctrl-Alt-R (or ⌘-Alt-R on Mac) or Enter to refresh. The Save icon lets you save the markdown file to disk
This is a preview from the server running through my markdig pipeline
يمكنك أن تجد كل رموز البيانات الخاصة بكتابات المدونات على: لا يُحَجْجَه
الجزء 2 من السلسلة المتعلقة بإضافة إطار الكيان إلى مشروع أساسي من مشاريع الشبكة. يمكن العثور على جزء من الجزء الأول هنا هنا.
في المقال السابق، أنشأنا قاعدة البيانات والسياق لمدوناتنا. وفي هذه الوظيفة، سنضيف الخدمات للتفاعل مع قاعدة البيانات.
وفي الوظيفة التالية، سنفصّل كيفية عمل هذه الخدمات الآن مع أجهزة المراقبة والآراء القائمة.
[رابعاً -
لدينا الآن فئة تمديد BlogSetup التي تنشئ هذه الخدمات. هذا امتداد لما فعلناه في الجزء الأولحيث أنشأنا قاعدة البيانات والسياق
public static void SetupBlog(this IServiceCollection services, IConfiguration configuration)
{
var config = services.ConfigurePOCO<BlogConfig>(configuration.GetSection(BlogConfig.Section));
services.ConfigurePOCO<MarkdownConfig>(configuration.GetSection(MarkdownConfig.Section));
switch (config.Mode)
{
case BlogMode.File:
services.AddScoped<IBlogService, MarkdownBlogService>();
services.AddScoped<IBlogPopulator, MarkdownBlogPopulator>();
break;
case BlogMode.Database:
services.AddDbContext<MostlylucidDbContext>(options =>
{
options.UseNpgsql(configuration.GetConnectionString("DefaultConnection"));
});
services.AddScoped<IBlogService, EFBlogService>();
services.AddScoped<IMarkdownBlogService, MarkdownBlogPopulator>();
services.AddScoped<IBlogPopulator, EFBlogPopulator>();
break;
}
}
هذا استخدام BlogConfig
لتحديد النمط الذي نحن فيه، إما File
أو Database
/ / / / وبناء على ذلك، نسجل الخدمات التي نحتاجها.
"Blog": {
"Mode": "File"
}
public class BlogConfig : IConfigSection
{
public static string Section => "Blog";
public BlogMode Mode { get; set; }
}
public enum BlogMode
{
File,
Database
}
كما أريد دعم كل من الملف وقاعدة البيانات في هذا التطبيق (لماذا لا)! لقد استخدمت أسلوباً قائماً على الواجهة يسمح لهم بالمبادلة على أساس التهيئة.
لدينا ثلاثة واجهات جديدة، IBlogService
, IMarkdownBlogService
وقد عقد مؤتمراً بشأن IBlogPopulator
.
هذا هو الواجهة الرئيسية لخدمة المدونين. وهو يتضمن أساليب للحصول على الوظائف والفئات وفرادى الوظائف.
public interface IBlogService
{
Task<List<string>> GetCategories();
Task<List<BlogPostViewModel>> GetPosts(DateTime? startDate = null, string category = "");
Task<PostListViewModel> GetPostsByCategory(string category, int page = 1, int pageSize = 10, string language = BaseService.EnglishLanguage);
Task<BlogPostViewModel?> GetPost(string slug, string language = "");
Task<PostListViewModel> GetPagedPosts(int page = 1, int pageSize = 10, string language = BaseService.EnglishLanguage);
Task<List<PostListModel>> GetPostsForLanguage(DateTime? startDate = null, string category = "", string language = BaseService.EnglishLanguage);
}
هذه الخدمة مستخدمة من قِبَل EFlogPopulatorService
في الجولة الأولى لكتابة قاعدة البيانات مع بيانات من ملفات الهدف.
public interface IMarkdownBlogService
{
Task<List<BlogPostViewModel>> GetPages();
Dictionary<string, List<String>> LanguageList();
}
كما يمكنك أن ترى أنه بسيط جداً وفقط لديه طريقتين، GetPages
وقد عقد مؤتمراً بشأن LanguageList
/ / / / تستخدم هذه لمعالجة ملفات العلامة و الحصول على قائمة اللغات.
تُستخدَم المدوّنات المُستخدِمة في طريقة إعدادنا أعلاه لحشو قاعدة البيانات أو كائنات المخابئ الساكنة (للنظام القائم على الملفات) بوظائف.
public static async Task PopulateBlog(this WebApplication app)
{
await using var scope = app.Services.CreateAsyncScope();
var config = scope.ServiceProvider.GetRequiredService<BlogConfig>();
if(config.Mode == BlogMode.Database)
{
var blogContext = scope.ServiceProvider.GetRequiredService<MostlylucidDbContext>();
await blogContext.Database.MigrateAsync();
}
var context = scope.ServiceProvider.GetRequiredService<IBlogPopulator>();
await context.Populate();
}
يمكنك أن ترى أن هذا امتداد إلى WebApplication
مع تشكيل يسمح لقاعدة البيانات الهجرة إلى التشغيل عند الحاجة (الذي ينشئ قاعدة البيانات أيضاً إذا لم تكن موجودة). ثم يدعو إلى المُعَد IBlogPopulator
(ب) الخدمات التي تقدم إلى الشبكة من أجل ملء قاعدة البيانات.
هذه هي واجهة تلك الخدمة.
public interface IBlogPopulator
{
Task Populate();
}
حق بسيط جداً؟ يجري تنفيذ هذا في كل من MarkdownBlogPopulator
وقد عقد مؤتمراً بشأن EFBlogPopulator
-الفصول الدراسية.
GetPages
(ب) وضع طريقة لضبط المخبأ ووضعه في المخبأ. /// <summary>
/// The method to preload the cache with pages and Languages.
/// </summary>
public async Task Populate()
{
await PopulatePages();
}
private async Task PopulatePages()
{
if (GetPageCache() is { Count: > 0 }) return;
Dictionary<(string slug, string lang), BlogPostViewModel> pageCache = new();
var pages = await GetPages();
foreach (var page in pages) pageCache.TryAdd((page.Slug, page.Language), page);
SetPageCache(pageCache);
}
IMarkdownBlogService
للحصول على الصفحات ومن ثم تُشَغّل قاعدة البيانات. public async Task Populate()
{
var posts = await markdownBlogService.GetPages();
var languages = markdownBlogService.LanguageList();
var languageEntities = await EnsureLanguages(languages);
await EnsureCategoriesAndPosts(posts, languageEntities);
await context.SaveChangesAsync();
}
لقد قسمنا هذه الخاصية إلى واجهات لجعل الشفرة أكثر تفهماً و "مفصلة" (كما هو الحال في مبادئ SolID). هذا يسمح لنا بمبادلة الخدمات بسهولة بناءً على التشكيل.
وفي الوظيفة التالية، سننظر بمزيد من التفصيل في تنفيذ المراقبين الماليين وآرائهم للاستفادة من هذه الخدمات.