public class OnlineUserMiddleWare { private readonly RequestDelegate _next; private readonly IMemoryCache _memoryCache; public OnlineUserMiddleWare(RequestDelegate next, IMemoryCache memoryCache) { _next = next; _memoryCache = memoryCache; } public async Task Invoke(HttpContext context) { if (!_memoryCache.TryGetValue("OnlineUsers", out Dictionary<string,DateTime> onlineUsers)) { onlineUsers = new Dictionary<string, DateTime>(); _memoryCache.Set("OnlineUsers", onlineUsers); } if (context.User.Identity.IsAuthenticated) { var name = context.User.Identity.Name; if (name != null) { if (onlineUsers.ContainsKey(name)) onlineUsers[name] = DateTime.Now; else onlineUsers.Add(name, DateTime.Now); } } foreach (var online in onlineUsers) { if (online.Value < DateTime.Now.AddMinutes(-10)) onlineUsers.Remove(online.Key); } await _next(context); } }
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IServiceProvider serviceProvider) { ... app.UseMiddleware<OnlineUserMiddleWare>(); ... }
public class DashboardController { private readonly IMemoryCache _memoryCache; public DashboardController(memoryCache) { _memoryCache = memoryCache; } public IActionResult Index() { _memoryCache.TryGetValue("OnlineUsers", out Dictionary<string, DateTime> onlineUsers); ViewBag.OnlineUsers = onlineUsers.Count; return View(); } }
if(context.Request.Path.StartsWithSegments("/Identity/Account/Login")) { foreach (var online in onlineUsers) { if (online.Value < DateTime.Now.AddMinutes(-10)) onlineUsers.Remove(online.Key); } }
5.Visual Studio 2017 15.8 منتشر شد
These are the customer-reported issues addressed in 15.8.5:
- Debugger tooltip does not expand in Xamarin.iOS debugging session.
- Debugger won't let me leave execution point (Android).
- After updating to 15.8.1, data tip does not show when debugging.
- Debugger data tip does not expand [Editor].
- Exception:MSB0001: Internal MSBuild Error: Already registered for build-time.
- Wrong path to resource in manifest for ClickOnce after upgrading to VS 15.8.1.
- ClickOnce Manifest error in 15.8.
- ClickOnce Publish is missing certain references.
- ClickOnce: Language file copied to wrong location.
- Reference missing in the ClickOnce publish folder.
- Compiling non-.NET SDK style F# projects results in an internal MSBuild error unless MSBuild parallelism is set to 1.
- F# is not NGEN'd in Visual Studio.
- F# deploys the FSharp.Core 4.5.0.0 binary in the 4.4.3.0 location.
Details of What's New in 15.8.5
Visual Studio Tools for Xamarin
Visual Studio Tools for Xamarin now supports Xcode 10, which allows you to build and debug apps for iOS 12, tvOS 12, and watchOS 5. See how to get ready for iOS 12 and our introduction to iOS 12 for more details on the new features available.
Memento یک الگوی طراحی مفید و ساده است که برای ذخیره و بازیابی state یک object استفاده میشود. در بعضی از مقالات از آن به عنوان snapshot نیز یاد شده است! اگر با git کار کرده باشید، این مفهوم را میتوان در git بسیار یافت؛ هر commit به عنوان یک snapshot میباشد که میتوان به صورت مکرر آن را undo کرد و یا مثال خیلی سادهتر میتوان به ctrl+z در سیستم عامل اشاره کرد.
به مثال زیر توجه کنید:
Int temp; Int a=1; temp=a; a=2; . . a=temp;
شما قطعا در برنامه نویسی با کد بالا زیاد برخورد داشتهاید و آنرا به صورت مکرر انجام دادهاید. کد بالا را در قالب یک object بیان میکنیم. به مثال زیر توجه کنید:
int main() { MyClass One = new MyClass(); MyClass Temp = new MyClass(); // Set an initial value. One.Value = 10; One.Name = "Ten"; // Save the state of the value. Temp.Value = One.Value; Temp.Name = One.Name; // Change the value. One.Value = 99; One.Name = "Ninety Nine"; // Undo and restore the state. One.Value = Temp.Value; One.Name = Temp.Name; }
در کد بالا با استفاده از یک temp، شیء مورد نظر را ذخیره کرده و در آخر مجدد دادهها را درون شیء، restore میکنیم.
از مشکلات کد بالا میتوان گفت :
۱- برای هر object باید یک شیء temp ایجاد کنیم.
۲- ممکن است بخواهیم که حالات یک object را بر روی هارد ذخیره کنیم. با روش فوق کدها خیلی پیچیدهتر خواهند شد.
۳- نوشتن کد به این سبک برای پروژههای بزرگ، پیچیده و مدیریت آن سختتر میشود.
پیاده سازی memento
ما این مثال را در قالب یک پروژه NET Core onsole. ایجاد میکنیم. برای این کار یک پوشهی جدید را ایجاد و درون ترمینال دستور زیر را وارد کنید:
dotnet new console
روشهای زیادی برای پیاده سازی memento وجود دارند. برای پیاده سازی memento ابتدا یک abstract class را به شکل زیر ایجاد میکنیم:
abstract class MementoBase { protected Guid mementoKey = Guid.NewGuid(); abstract public void SaveMemento(Memento memento); abstract public void RestoreMemento(Memento memento); }
اگر به کلاس بالا دقت کنید، این کلاس قرار است parent کلاسهای دیگری باشد که داری دو متد SaveMemento و RestoreMemento برای ذخیره و بازیابی و همچنین یک Guid برای نگهداری stateهای مختلف میباشد.
ورودی متدها از نوع memento میباشد. پس کلاس memento را به شکل زیر ایجاد میکنیم:
class Memento { private Dictionary<Guid, object> stateList = new Dictionary<Guid, object>(); public object GetState(Guid key) { return stateList[key]; } public void SetState(Guid key, object newState) { stateList[key] = newState; } public Memento() { } }
در کد بالا با یک Dictionary میتوان هر object را با کلیدش ذخیره کنیم. توجه کنید که value دیکشنری از نوع object میباشد و چون object پدر تمام objectهای دیگر است پس میتوانیم هر نوع دادهای را در آن ذخیره کنیم. تا اینجا، Memento پیاده سازی شده است. میتوان این کار را با جنریکها نیز پیاده سازی کرد.
در ادامه میخواهیم یک کلاس بسازیم و حالتهای مختلف را در آن بررسی کنیم. کلاس زیر را ایجاد کنید:
class ConcreteOriginator : MementoBase { private int value = 0; public ConcreteOriginator(int newValue) { SetData(newValue); } public void SetData(int newValue) { value = newValue; } public void Speak() { Console.WriteLine("My value is " + value.ToString()); } public override void SaveMemento(Memento memento) { memento.SetState(mementoKey, value); } public override void RestoreMemento(Memento memento) { int restoredValue = (int)memento.GetState(mementoKey); SetData(restoredValue); } }
کلاس ConcreteOriginator از کلاس MementoBase ارث بری کرده و دو متد RestoreMemento و SaveMemento را پیاده سازی میکند و همچنین دارای یک مشخصه value میباشد. برای خروجی گرفتن، متد main را به صورت زیر پیاده سازی میکنیم:
static void Main(string[] args) { Memento memento = new Memento(); // Create an originator, which will hold our state data. ConcreteOriginator myOriginator = new ConcreteOriginator("Hello World!", StateType.ONE); ConcreteOriginator anotherOriginator = new ConcreteOriginator("Hola!", StateType.ONE); ConcreteOriginator2 thirdOriginator = new ConcreteOriginator2(7); // Set some state data. myOriginator.Speak(); anotherOriginator.Speak(); thirdOriginator.Speak(); // Save the states into our memento. myOriginator.SaveMemento(memento); anotherOriginator.SaveMemento(memento); thirdOriginator.SaveMemento(memento); // Now change our originators' states. myOriginator.SetData("Goodbye!", StateType.TWO); anotherOriginator.SetData("Adios!", StateType.TWO); thirdOriginator.SetData(99); myOriginator.Speak(); anotherOriginator.Speak(); thirdOriginator.Speak(); // Restore our originator's state. myOriginator.RestoreMemento(memento); anotherOriginator.RestoreMemento(memento); thirdOriginator.RestoreMemento(memento); myOriginator.Speak(); anotherOriginator.Speak(); thirdOriginator.Speak(); Console.ReadKey(); }
Hello World! I'm in state ONE Hola! I'm in state ONE My value is 7 Goodbye! I'm in state TWO Adios! I'm in state TWO My value is 99 Hello World! I'm in state ONE Hola! I'm in state ONE My value is 7
Docker برای توسعه دهندگان دات نت
پشتیبانی از VB.NET در NET 5.
Kweb is a library for building web applications in the Kotlin programming language, that virtually eliminates the separation between browser and server from the programmer’s perspective