نحوه افزودن Nuget Package ها به Template؟
Roslyn #1
PM> Uninstall-package Microsoft.CodeDom.Providers.DotNetCompilerPlatform PM> Uninstall-package Microsoft.Net.Compilers
<Target Name="CopyRoslynFiles" AfterTargets="AfterBuild" Condition="!$(Disable_CopyWebApplication) And '$(OutDir)' != '$(OutputPath)'"> <ItemGroup> <RoslynFiles Include="$(CscToolPath)\*" /> </ItemGroup> <MakeDir Directories="$(WebProjectOutputDir)\bin\roslyn" /> <Copy SourceFiles="@(RoslynFiles)" DestinationFolder="$(WebProjectOutputDir)\bin\roslyn" SkipUnchangedFiles="true" Retries="$(CopyRetryCount)" RetryDelayMilliseconds="$(CopyRetryDelayMilliseconds)" /> </Target>
<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> <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+"></compiler> </compilers> </system>
LINQ یک DLS بر مبنای .NET می باشد که برای پرس و جو در منابع داده ای مانند پایگاههای داده ، فایلهای XML و یا لیستی از اشیاء درون حافظه کاربرد دارد.
یکی از بزرگترین مزیتهای آن Syntax آسان و خوانا آن میباشد.
LINQ از 2 نوع نمادگذاری پشتیبانی میکند:
- Inline LINQ یا query expressions :
var result = from product in dbContext.Products where product.Category.Name == "Toys" where product.Price >= 2.50 select product.Name;
- Fluent Syntax :
var result = dbContext.Products .Where(p => p.Category.Name == "Toys" && p.Price >= 250) .Select(p => p.Name);
در پرس و چوهای بالا فیلدهای مورد نیاز در قسمت Select در زمان Compile شناخته شده هستند . اما گاهی ممکن است فیلدهای مورد نیاز در زمان اجرا مشخص شوند.
به عنوان مثال یک گزارش ساز پویا که کاربر مشخص میکند چه ستون هایی در خروجی نمایش داده شوند یا یک جستجوی پیشرفته که ستونهای خروجی به اختیار کاربر در زمان اجرا مشخص میشوند.
این مدل را در نظر داشته باشید :
public class Student { public int Id { get; set; } public string Name { get; set; } public string Field1 { get; set; } public string Field2 { get; set; } public string Field3 { get; set; } public static IEnumerable<Student> GetStudentSource() { for (int i = 0; i < 10; i++) { yield return new Student { Id = i, Name = "Name " + i, Field1 = "Field1 " + i, Field2 = "Field2 " + i, Field3 = "Field3 " + i }; } } }
ستونهای کلاس Student را در رابط کاربری برنامه جهت انتخاب به کاربر نمایش میدهیم. سپس کاربر یک یا چند ستون را انتخاب میکند که قسمت Select کوئری برنامه باید بر اساس فیلدهای مورد نظر کاربر مشخص شود.
یکی از روش هایی که میتوان از آن بهره برد استفاده از کتاب خانه Dynamic LINQ معرفی شده در اینجا می باشد.
این کتابخانه جهت سهولت در نصب به کمک NuGet در این آدرس قرار دارد.
فرض بر این است که فیلدهای انتخاب شده توسط کاربر با "," از یکدیگر جدا شده اند.
public class Program { private static void Main(string[] args) { System.Console.WriteLine("Specify the desired fields : "); string fields = System.Console.ReadLine(); IEnumerable<Student> students = Student.GetStudentSource(); IQueryable output = students.AsQueryable().Select(string.Format("new({0})", fields)); foreach (object item in output) { System.Console.WriteLine(item); } System.Console.ReadKey(); } }
همانطور که در عکس ذیل مشاهده میکنید پس از اجرای برنامه ، فیلدهای انتخاب شده توسط کاربر از منبع دادهی دریافت شده و در خروجی نمایش داده شده اند.
این روش مزایا و معایب خودش را دارد ، به عنوان مثال خروجی یک لیست از شیء Student نیست یا این Select فقط برای روی یک شیء IQueryable قابل انجام است.
روش دیگری که میتوان از آن بهره جست استفاده از یک متد کمکی جهت تولید پویای عبارت Lambda ورودی Select می باشد :
public class SelectBuilder <T> { public static Func<T, T> CreateNewStatement(string fields) { // input parameter "o" var xParameter = Expression.Parameter(typeof(T), "o"); // new statement "new T()" var xNew = Expression.New(typeof(T)); // create initializers var bindings = fields.Split(',').Select(o => o.Trim()) .Select(o => { // property "Field1" var property = typeof(T).GetProperty(o); // original value "o.Field1" var xOriginal = Expression.Property(xParameter, property); // set value "Field1 = o.Field1" return Expression.Bind(property, xOriginal); } ).ToList(); // initialization "new T { Field1 = o.Field1, Field2 = o.Field2 }" var xInit = Expression.MemberInit(xNew, bindings); // expression "o => new T { Field1 = o.Field1, Field2 = o.Field2 }" var lambda = Expression.Lambda<Func<T, T>>(xInit, xParameter); // compile to Func<T, T> return lambda.Compile(); } }
IEnumerable<Student> result = students.Select(SelectBuilder<Student>.CreateNewStatement("Field1, Field2")).ToList(); foreach (Student student in result) { System.Console.WriteLine(student.Field1); }
ابتدا فیلدهای انتخابی کاربر که با "," جدا شده اند به ورودی پاس داده میشود سپس یک statement خالی ایجاد میشود :
o=>new Student()
var property = typeof(T).GetProperty(o);
بروز خطا
نگاهی به گزینههای مختلف مهیای جهت میزبانی SignalR
1) OWIN
2) ASP.NET Hosting
3) Self Hosting
4) Cloud و ویندوز Azure
1) OWIN
اگر به اسمبلیهای همراه با SignalR دقت کنید، یکی از آنها Microsoft.AspNet.SignalR.Owin.dll نام دارد. OWIN مخفف Open web server interface for .NET است و کار آن ایجاد لایهای بین وب سرورها و برنامههای وب میباشد. یکی از اهداف مهم آن ترغیب دنیای سورس باز به تهیه ماژولهای مختلف قابل استفاده در وب سرورهای دات نتی است. نکتهی مهمی که در SignalR و کلیه میزبانهای آن وجود دارد، بنا شدن تمامی آنها برفراز OWIN میباشد.
2) ASP.NET Hosting
بدون شک، میزبانی ASP.NET از هابهای SignalR، مرسومترین روش استفاده از این فناوری میباشد. این نوع میزبانی نیز برفراز OWIN بنا شده است. نصب آن توسط اجرای دستور پاور شل ذیل در یک پروژه وب صورت میگیرد:
PM> Install-Package Microsoft.AspNet.SignalR
3) خود میزبانی یا Self hosting
خود میزبانی نیز برفراز OWIN تهیه شده است و برای پیاده سازی آن نیاز است وابستگیهای مرتبط با آن، از طریق NuGet به کمک فرامین پاور شل ذیل دریافت شوند:
PM> Install-Package Microsoft.AspNet.SignalR.Owin PM> Install-Package Microsoft.Owin.Hosting -Pre PM> Install-Package Microsoft.Owin.Host.HttpListener -Pre
مراحل تهیه یک برنامه ثالث (برای مثال خارج از IIS یا یک وب سرور آزمایشی) به عنوان میزبان Hubs مورد نیاز به این شرح هستند:
الف) کلاس آغازین میزبان باید با پیاده سازی اینترفیسی به نام IAppBuilder تهیه شود.
ب) مسیریابیهای مورد نیاز تعریف گردند.
ج) وب سرور HTTP یا HTTPS توکار برای سرویس دهی آغاز گردد.
باید توجه داشت که در این حالت برخلاف روش ASP.NET Hosting، سایر اسمبلیهای برنامه جهت یافتن Hubهای تعریف شده، اسکن نمیشوند. همچنین هنگام کار با jQuery مباحث عنوان شده در مورد تنظیم دسترسیهای Cross domain نیز باید در اینجا اعمال گردند. به علاوه اجرای وب سرور توکار آن به دلایل امنیتی، نیاز به دسترسی مدیریتی دارد.
برای پیاده سازی یک نمونه، به برنامهای که تاکنون تهیه کردهایم، یک پروژه کنسول دیگر را به نام ConsoleHost اضافه کنید. البته باید درنظر داشت در دنیای واقعی این نوع برنامهها را عموما از نوع سرویسهای ویندوز NT تهیه میکنند.
در ادامه سه فرمان پاور شل یاد شده را برای افزودن وابستگیهای مورد نیاز فراخوانی نمائید. همچنین باید دقت داشت که این دستور بر روی پروژه جدید اضافه شده باید اجرا گردد.
using System; using Microsoft.AspNet.SignalR; using Microsoft.AspNet.SignalR.Hubs; using Microsoft.Owin.Hosting; using Owin; namespace SignalR02.ConsoleHost { public class Startup { public void Configuration(IAppBuilder app) { app.MapHubs(new HubConfiguration { EnableCrossDomain = true }); } } [HubName("chat")] public class ChatHub : Hub { public void SendMessage(string message) { var msg = string.Format("{0}:{1}", Context.ConnectionId, message); Clients.All.hello(msg); } } class Program { static void Main(string[] args) { using (WebApplication.Start<Startup>("http://localhost:1073/")) { Console.WriteLine("Press a key to terminate the server..."); Console.Read(); } } } }
سمت کلاینت استفاده از آن هیچ تفاوتی نمیکند و با جزئیات آن پیشتر آشنا شدهاید؛ برای مثال در کلاینت جیکوئری خاصیت connection.hub.url باید به مسیر جدید سرور هاب تنظیم گردد تا اتصالات به درستی برقرار شوند.
دریافت پروژه کامل مرتبط با این 4 قسمت (البته بدون فایلهای باینری آن، جهت کاهش حجم 32 مگابایتی)
SignalRSamples.zip
DebuggerStepThroughAttribute
class Program { public static void Main(string[] args) { DebuggerStepThroughMethod1(); } [DebuggerStepThrough] public static void DebuggerStepThroughMethod1() { Console.WriteLine( "Method 1" ); DebuggerStepThroughMethod2(); } [DebuggerStepThrough] public static void DebuggerStepThroughMethod2() { Console.WriteLine( "Method 2" ); } }
ConditionalAttribute
class Program { public static void Main(string[] args) { DebugMode(); } [Conditional("DEBUG")] public static void DebugMode() { Console.WriteLine( "Debug mode" ); } }
#define ReleaseMode
Flags Enum Attribute
[System.Flags] public enum Permission { View = 1, Insert = 2, Update = 4, Delete = 8 }
public static void Main( string[] args ) { var permission = ( Permission.View | Permission.Insert ).ToString(); Console.WriteLine( permission ); // Displays ‘View, Insert’ var userPermission = Permission.View | Permission.Insert | Permission.Update | Permission.Delete; // To retrieve the value from property you can do this if ( ( userPermission & Permission.Delete ) == Permission.Delete ) { Console.WriteLine( "کاربر دارای مجوز دسترسی به عملیات حذف میباشد" ); } // In .NET 4 and later Console.WriteLine( userPermission.HasFlag( Permission.Delete ) ? "کاربر دارای مجوز دسترسی به عملیات حذف میباشد" : "کاربر مجوز دسترسی به عملیات حذف را ندارد"); }
نکته: در صورتیکه مقداری را برای enum تعریف کرده باشید، نمیتوانید آن را با مقدار 0 مشخص کنید (در زمانی که ویژگی flags را بر روی enum اضافه کرده باشید)، چرا که با استفاده از عملیات بیتی AND نمیتوانید دارا بودن آن مقدار را تست کنید و همیشه نتیجه صفر خواهد بود.
Dynamically Compile and Execute C# Code
CodeDOM
public static void Main( string[] args ) { var sourceCode = @"class DotNetTips { public void Print() { System.Console.WriteLine("".Net Tips""); } }"; var compiledAssembly = CompileSourceCodeDom( sourceCode ); ExecuteFromAssembly( compiledAssembly ); } static Assembly CompileSourceCodeDom( string sourceCode ) { CodeDomProvider csharpCodeProvider = new CSharpCodeProvider(); var cp = new CompilerParameters { GenerateExecutable = false }; cp.ReferencedAssemblies.Add( "System.dll" ); var cr = csharpCodeProvider.CompileAssemblyFromSource( cp, sourceCode ); return cr.CompiledAssembly; }
Roslyn
سکوی کامپایلر دات نت " Roslyn "، کامپایلرهای متن باز #C و VB.NET را به همراه APIهای تجزیه و تحلیل کد ارائه کرده است که با استفاده از این APIها میتوان ابزارهای آنالیز کد جهت استفاده در ویژوال استودیو را ایجاد کرد.
برای استفاده از Roslyn باید این کتابخانه را نصب کنید
Install-Package Microsoft.CodeAnalysis
حال مثال قبل را با استفاده از Roslyn بازنویسی میکنیم:
public static void Main(string[] args) { var sourceCode = @"class DotNetTips { public void Print() { System.Console.WriteLine("".Net Tips""); } }"; var compiledAssembly = CompileSourceRoslyn( sourceCode ); ExecuteFromAssembly( compiledAssembly ); } private static Assembly CompileSourceRoslyn(string sourceCode) { using ( var memoryStream = new MemoryStream() ) { var assemblyFileName = string.Concat( Guid.NewGuid().ToString(), ".dll" ); var compilation = CSharpCompilation.Create( assemblyFileName, new[] { CSharpSyntaxTree.ParseText( sourceCode ) }, new[] { MetadataReference.CreateFromFile( typeof( object ).Assembly.Location ) }, new CSharpCompilationOptions( OutputKind.DynamicallyLinkedLibrary ) ); compilation.Emit( memoryStream ); var assembly = Assembly.Load( memoryStream.GetBuffer() ); return assembly; } }
و جهت فراخوانی اسمبلی ساخته شده به هر دو روش بالا، از کد زیر استفاده میکنیم.
static void ExecuteFromAssembly( Assembly assembly ) { var helloKittyPrinterType = assembly.GetType( "DotNetTips" ); var printMethod = helloKittyPrinterType.GetMethod( "Print" ); var kitty = assembly.CreateInstance( "DotNetTips" ); printMethod.Invoke( kitty, BindingFlags.InvokeMethod, null, null, CultureInfo.CurrentCulture ); }
Rider 2024.2.5 منتشر شد
بررسی حباب Bun
تفکر درباره mvc 5,mvc 6,mvc flash 3
Over five years ago I released MvcFlash, and soon after I released the second iteration MvcFlash2. Don't let the terrible naming and versioning fool you, this is one of my favorite creations. As ASP.NET 5 starts to take root and MVC 6 blossoms, I begin to feel more confident about creating the next version of MvcFlash. Honestly, I can't see developing an MVC application without it. Before I do, I thought I would muse about the possible challenges ahead.