An Introduction to .NET MAUI For Mobile Development
.NET Multi-platform App UI (.NET MAUI) is a cross-platform framework for creating native mobile and desktop apps with C# and XAML.
.NET MAUI is open-source and is the evolution of Xamarin.Forms, extended from mobile to desktop scenarios, with UI controls rebuilt from the ground up for performance and extensibility. If you've previously used Xamarin.Forms to build cross-platform user interfaces, you'll notice many similarities with .NET MAUI. However, there are also some differences. Using .NET MAUI, you can create multi-platform apps using a single project, but you can add platform-specific source code and resources if necessary. One of the key aims of .NET MAUI is to enable you to implement as much of your app logic and UI layout as possible in a single code-base.
0:00 - Setup Visual Studio and MAUI Project
00:16:25 - Create MAUI Pages with C#
00:27:42 - Create MAUI Pages with XAML
00:32:28 - Explore MAUI Layouts
00:39:38 - Static Shared Resources
00:44:36 - Platform Specific Values
00:50:11 - Page Navigation
برای افرادی که برنامه نویسی IoT علاقه دارند، Raspberry Pi 3 یک سخت افزار هیجان انگیز به حساب میآید. مهمترین ویژگی این مدل نسبت به مدلهای قبلی وجود Builtin WiFi در آن میباشد. در این مقاله از Scott Hanselman نشان داده شده که چطور با استفاده از زبان JavaScript و VS Code میتوان روی این سختافزار کد نوشت.
وضعیت WebAssembly در 2021 و 2022
2021 was no exception and the following are some of the new areas where you’ll now find WebAssembly
-
- The Disney+ Application Development Kit is using WebAssembly: https://medium.com/disney-streaming/introducing-the-disney-application-development-kit-adk-ad85ca139073
- A simplified version of Photoshop on the web was released: https://www.theverge.com/2021/10/26/22738125/adobe-photoshop-illustrator-web-announced
- Microsoft’s Flight Simulator has a WebAssembly-based plugin system: https://docs.flightsimulator.com/html/Programming_Tools/WASM/WebAssembly.htm
MongoDB #13
>db.COLLECTION_NAME.aggregate(AGGREGATE_OPERATION)
{ _id: ObjectId(7df78ad8902c) title: 'MongoDB Overview', description: 'MongoDB is no sql database', by_user: 'user1', url: 'http://www.site.com', tags: ['mongodb', 'database', 'NoSQL'], likes: 100 }, { _id: ObjectId(7df78ad8902d) title: 'NoSQL Overview', description: 'No sql database is very fast', by_user: 'user1', url: 'http://www.site.com', tags: ['mongodb', 'database', 'NoSQL'], likes: 10 }, { _id: ObjectId(7df78ad8902e) title: 'Neo4j Overview', description: 'Neo4j is no sql database', by_user: 'Neo4j', url: 'http://www.neo4j.com', tags: ['neo4j', 'database', 'NoSQL'], likes: 750 },
> db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : 1}}}]) { "result" : [ { "_id" : "user1", "num_tutorial" : 2 }, { "_id" : "Neo4j", "num_tutorial" : 1 } ], "ok" : 1 } >
select by_user, count(*) from mycol group by by_user
عبارت | توضیحات | مثال |
$sum | مقدار تعیین شده از همه سندهای مجموعه را جمع میکند. | db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : "$likes"}}}]) |
$avg | میانگین همه مقادیر بدست آمده از سندهای مجموعه را محاسبه میکند. | db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$avg : "$likes"}}}]) |
$min | کمترین مقادیر مشابه را از همه سندهای مجموعه، بر میگرداند. | db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$min : "$likes"}}}]) |
$max | بیشترین مقادیر مشابه را از همه سندهای مجموعه، بر میگرداند. | db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$max : "$likes"}}}]) |
$push | یک مقدار را در سند نتیجه، در یک آرایه درج میکند. | db.mycol.aggregate([{$group : {_id : "$by_user", url : {$push: "$url"}}}]) |
$addToSet | یک مقدار را در سند نتیجه در یک آرایه درج میکند، اما مقدار تکراری ایجاد نمیکند. | db.mycol.aggregate([{$group : {_id : "$by_user", url : {$addToSet : "$url"}}}]) |
$first | اولین سند از اسناد را برطبق گروه بندی بر میگرداند. معمولا این عبارت بعد از عبارتهای مرتب سازی مرحلهای استفاده میشود. | db.mycol.aggregate([{$group : {_id : "$by_user", first_url : {$first : "$url"}}}]) |
$last | آخرین سند از اسناد را برطبق گروه بندی بر میگرداند. معمولا این عبارت بعد از عبارتهای مرتب سازی مرحلهای استفاده میشود. | db.mycol.aggregate([{$group : {_id : "$by_user", last_url : {$last : "$url"}}}]) |
- $project : برای انتخاب چندین فیلد از یک مجموعه استفاده میشود.
- $match : این یک عملگر فیلترگذاری است که میتواند میزان اسنادی را که بعنوان ورودی در مرحله بعد گرفته میشوند، کاهش دهد.
- $group : این همان تابع جمعی است که در بالا توضیح داده شد.
- $skip : توسط این عبارت، در یک لیست بدست آمده (نتیجه)، میتوانید از لیست اسناد بصورت روبه جلو صرفنظر کنید.
- $limit : این عبارت تعداد اسناد را توسط عدد گرفته شده، از موقعیت فعلی برای نمایش محدود میکند.
- $unwind : این عبارت برای باز کردن (unwind) سندی که از آرایهها بهره گیری میکند استفاده میشود. وقتی از آرایه استفاده میکنید، داده از نوع پیش پیوست (Pre-joined) است و با این نوع داده، این عمل برای داشتن سندهای اختصاصی نا تمام خواهد ماند. بنابراین با این مرحله میتوانید میزان اسناد را برای مرحله بعد افزایش دهید.
Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyDbContext, Configuration>());
An exception occurred while initializing the database. See the InnerException for details. به وجود میآید و البته دیتابیس در SQL Server ایحاد شده و فقط در زمان ارسال هر گونه کوری به لایه سرویس این مورد پیش میآید .
اما با جایگرین شدن در قسمت Application_Start() از
Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyDbContext, Configuration>());
Database.SetInitializer<MoneyExDbContext>(null);
در بسیاری اوقات ممکن است تیم تحلیل دیتابیس، از توسعه اپلیکیشن جدا شده باشد تا مراحل نرمال سازی و تست بهره وری اجرای کوئریها، بهصورت جداگانهای از توسعهی برنامه انجام شود؛ یا ممکن است دیتابیس یک برنامهی از پیش موجود، برای نگهداری و مهندسی مجدد به شما سپرده شود. سناریو هر چه باشد، جهت سرعت بخشیدن به توسعهی نرم افزار میتوان از Entity Framework Core جهت ایجاد فایلهای Model از روی دیتابیس موجود استفاده کرد.
در این مثال ، از دیتابیس SQL Server و یک برنامهی کنسول و همچنین از ابزار NET Core CLI. استفاده خواهیم کرد.
با استفاده از ابزار CLI ابتدا یک فولدر خالی به نام EfCoreDbToModel ایجاد میکنیم:
> mkdir EfCoreDbToModel
> cd EfCoreDbToModel
> dotnet new console
> dotnet add package Microsoft.EntityFrameworkCore.SqlServer
> dotnet add package Microsoft.EntityFrameworkCore.Tools
> dotnet add package Microsoft.EntityFrameworkCore.SqlServer.Design
در ادامه فایل csproj. را باز کرده و در صورتیکه خط زیر در آن موجود نیست، آن را به گره ItemGroup اضافه کنید:
< DotNetCliToolReference Include= " Microsoft.EntityFrameworkCore.Tools.DotNet " Version= " 2.0.0 " />
> dotnet restore
اکنون با اجرای دستوری مثل دستور زیر، بررسی کنید که آیا دستورات Ef Core در دسترس هستند یا خیر:
> dotnet ef -h
برای تولید فایلهای Model، از دستور dbContext scaffold بصورت زیر استفاده میکنیم:
>dotnet ef dbcontext scaffold "Server=.;Database=Your_DB;Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer -o Model
1- Connection String
2- Provider که Entity Framework Core Provider مخصوص دیتابیس مدنظر شماست.
لیستی از دیتابیسهای مورد پشتیبانی EF Core را میتوانید در اینجا مشاهده کنید.
پس از اجرای دستور فوق، فولدر Model، شامل فایلهای Entity و همچنین یک فایل دیگر که معرف DbContext است، ایجاد خواهند شد:
گزینهی o- دایرکتوری ایجاد فایلهای مدل و DbContext را مشخص میکند. در صورتیکه از وارد کردن آن صرف نظر کنید، این فایلها بصورت پیش فرض در مسیری قرار خواهند گرفت که فایل csproj. وجود دارد.
همانطور که ملاحظه میکنید نام کلاس DbContext از ترکیب نام دیتابیس بعلاوهی کلمه “Context” خواهد بود. جهت تغییر نام این کلاس میتوانید از گزینهی "context "Your_Context_Title- استفاده نمائید. برای مثال:
> dotnet ef dbcontext scaffold "Server=.\;Database=Your_Db_name;Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer -o Model -context "MyDbContext"
جهت کسب اطلاعات بیشتر رجوع کنید به ^ و ^.
NOSQL قسمت سوم
در مطلب قبلی با نوع اول پایگاههایداده NoSQL یعنی Key/Value Store آشنا شدیم و در این مطلب به معرفی دسته دوم یعنی Document Database خواهیم پرداخت.
در این نوع پایگاه داده ، دادهها مانند نوع اول در قالب
کلید/مقدار ذخیره میشوند و بازگردانی مقادیر نیز دقیقا مشابه نوع اول یعنی Key/Value Store بر اساس کلید میباشد. اما
تفاوت این سیستم با نوع اول در دستهبندی دادههای مرتبط با یکدیگر در قالب یک Document میباشد. سعی کردم در این مطلب با ذکر مثال مطالب را شفافتر بیان کنم:
به عنوان مثال اگر بخواهیم جداول مربوط به پستهای یک سیستم CMS را بصورت رابطهای پیاده کنیم ، یکی از سادهترین حالات پایه برای پستهای این سیستم در حالت نرمال به صورت زیر میباشد.
جداول واضح بوده و نیازی به توضیح ندارد ، حال نحوهی ذخیرهسازی دادهها در سیستم Document Database برای چنین مثالی را بررسی میکنیم:
{ _id: ObjectID(‘4bf9e8e17cef4644108761bb’), Title: ‘NoSQL Part3’, url: ‘https://www.dntips.ir/yyy/xxxx’, author: ‘hamid samani’, tags: [‘databases’,’mongoDB’], comments:[ {user: ‘unknown user’, text:’unknown test’ }, {user:unknown user2’, text:’unknown text2 } ] }
همانگونه که مشاهد میکنید نحوهی ذخیرهسازی دادهها بسیار با سیستم رابطهای متفاوت میباشد ، با جمعبندی تفاوت نحوهی نگهداری دادهها در این سیستم و RDBMS و بررسی این سیستم نکات اصلی به شرح زیر میباشند:
۱-فرمت ذخیره سازی دادهها مشابه فرمت JSON میباشد.
۲-به مجموعه دادههای مرتبط به یکدیگر Document گفته میشود.
۳-در این سیستم JOIN ها وجود ندارند و دادههای مرتبط کنار یکدیگر قرار میگیرند ، و یا به تعریف دقیقتر دادهها در یک داکیومنت اصلی Embed میشوند.
به عنوان مثال در اینجا مقدار commentها برابر با آرایهای از Documentها میباشد.
۴-مقادیر میتوانند بصورت آرایه نیز در نظر گرفته شوند.
۵-در سیستمهای RDBMS در صورتی که بخواهیم از وجود JOINها صرفنظر کنیم. به عدم توانایی در نرمالسازی برخواهیم خورد که یکی از معایب عدم نرمالسازی وجود مقادیر Null در جداول میباشد؛ اما در این سیستم به دلیل Schema free بودن میتوان ساختارهای متفاوت برای Documentها در نظر گرفت.
به عنوان مثال برای یک پست میتوان مقدار n کامنت تعریف کرد و برای پست دیگر هیچ کامنتی تعریف نکرد.
۶-در این سیستم اصولا نیازی به تعریف ساختار از قبل موجود
نمیباشد و به محض اعلان دستور قرار دادن دادهها در پایگاهداده ساختار متناسب
ایجاد میشود.
با مقایسه دستورات CRUD در هر دو نوع پایگاه داده با نحوهی کوئری گرفتن از Document Database آشنا میشویم:
در SQL برای ایجاد جدول خواهیم داشت:
CREATE TABLE posts ( id INT NOT NULL AUTO_INCREMENT, author_id INT NOT NULL, url VARCHAR(50), PRIMARY KEY (id) )
دستور فوق در Document Database معادل است با:
db.posts.insert({id: “256” , author_id:”546”,url:"http://example.com/xxx"}) // با قرار دادن مقدار نوع ساختار مشخص میشود
در SQL جهت خواندن خواهیم داشت:
SELECT * from posts WHERE author_id > 100
db.posts.find({author_id:{$gt:”1000”}})
در SQL جهت بروزرسانی داریم:
UPDATE posts SET author_id= "123"
db.posts.update({ $set: { author_id: "123" }})
در SQL جهت حذف خواهیم داشت:
DELETE FROM posts WHERE author_id= "654"
که معادل است با:
db.posts.remove( { author_id: "654" } )
همانگونه که مشاهده میفرمایید نوشتن کوئری برای این پایگاه داده ساده بوده و زبان آن نیز بر پایه جاوا اسکریپت میباشد که برای اکثر برنامهنویسان قابل درک است.
تاکنون توسط شرکتهای مختلف پیادهسازیهای مختلفی از این سیستم انجام شده است که از مهمترین و پر استفادهترین آنها میتوان به موارد زیر اشاره کرد:
- Persia .NET این بار برای Silverlight | www.persiadevelopers.com
- استفاده از iTextSharp برای ایجاد فایلهای PDF | www.yazdinezhad.com
- کروم با عبور از فایرفاکس، دومین مرورگر محبوب دنیا شد - وبلاگینا | weblogina.com
- HTML5 for ASP.NET Developers | geekswithblogs.net
- tSQLt - Database Unit Testing for SQL Server | tsqlt.org
- BloggerAutoPoster-V1.6 منتشر شد | bap.codeplex.com
- CSS Editor جدید در ویژوال استودیوی بعدی | weblogs.asp.net
- تازههای WPF 4.5 ، ایجاد تاخیرحین انقیاد دادهها | 10rem.net
- راهنمای ایجاد اولین برنامه سبک مترو خود، با کمک سیشارپ، وی بی و سی++ | msdn.microsoft.com
- معرفی Modernizr | weblogs.asp.net
- معرفی برنامه Project2NuGet | www.dknaack.com