Rider EAP 20 منتشر شد.
Rider EAP 20 fixes a number of bugs, improves .NET Core support, has better NuGet performance, supports Xamarin Android applications, comes with Node.js tooling from WebStorm (including SpyJS), can generate ResX files, executes T4 templates (needs Windows and Visual Studio SDK), adds support for scratch files, … Too much for one sentence, as you can see from the full list of fixes. We’ll highlight a few, read on!
ده دلیل برتری Visual Basic نسبت به #C!
این جدیه یا طنزه؟ کامنتهای زیرشو بخونید، یه عده دیگه اومدن به چالش کشیدن مطلبو!
من با این که مدتی طولانی VB کار میکردم (البته خیلی وقتم هست که دیگه VB کار نمیکنم) ولی تا به حال نمیدونستم وی بی کاری پیدا بشه که C++ رو این شکلی ببینه:
اینو ببینید:
Subject: | Finally someone with sense |
Message: | C#
is an attempt to appease a group of idiots that where using an
antiquated language like C++ which was an attempt to appease idiots that
where using an antiquated language like ANSI C which was an attempt to
appease idiots that where using K&R C. The idea was bad from the start. It has always been a poorly designed language that simply drives up development costs. While it might have been good in the 70's, now it makes as much sense as coding in assembler. |
تغییرات کتابخانه DNTFrameworkCore
public interface ICreationTracking { DateTime CreatedDateTime { get; set; } } public interface IModificationTracking { DateTime? ModifiedDateTime { get; set; } }
public interface IHasRowIntegrity { string Hash { get; set; } } public interface IHasRowVersion { byte[] Version { get; set; } }
public abstract class AggregateRoot<TKey> : Entity<TKey>, IAggregateRoot where TKey : IEquatable<TKey> { private readonly List<IDomainEvent> _events = new List<IDomainEvent>(); public IReadOnlyCollection<IDomainEvent> Events => _events.AsReadOnly(); protected virtual void AddDomainEvent(IDomainEvent newEvent) { _events.Add(newEvent); } public virtual void ClearEvents() { _events.Clear(); } }
public static class EventBusExtensions { public static Task TriggerAsync(this IEventBus bus, IEnumerable<IDomainEvent> events) { var tasks = events.Select(async domainEvent => await bus.TriggerAsync(domainEvent)); return Task.WhenAll(tasks); } public static async Task PublishAsync(this IEventBus bus, IAggregateRoot aggregateRoot) { await bus.TriggerAsync(aggregateRoot.Events); aggregateRoot.ClearEvents(); } }
public interface IKeyValueService : IApplicationService { Task SetValueAsync(string key, string value); Task<Maybe<string>> LoadValueAsync(string key); Task<bool> IsTamperedAsync(string key); } public class KeyValue : Entity, IModificationTracking, ICreationTracking, IHasRowIntegrity { public string Key { get; set; } [Encrypted] public string Value { get; set; } public string Hash { get; set; } public DateTime CreatedDateTime { get; set; } public DateTime? ModifiedDateTime { get; set; } }
public class ExceptionOptions { public List<ExceptionMapItem> Mappings { get; } = new List<ExceptionMapItem>(); [Required] public string DbException { get; set; } [Required] public string DbConcurrencyException { get; set; } [Required] public string InternalServerIssue { get; set; } public bool TryFindMapping(DbException dbException, out ExceptionMapItem mapping) { mapping = null; var words = new HashSet<string>(Regex.Split(dbException.ToStringFormat(), @"\W")); var mappingItem = Mappings.FirstOrDefault(a => a.Keywords.IsProperSubsetOf(words)); if (mappingItem == null) { return false; } mapping = mappingItem; return true; } }
"Exception": { "Mappings": [ { "Message": "به دلیل وجود اطلاعات وابسته امکان حذف وجود ندارد", "Keywords": [ "DELETE", "REFERENCE" ] }, { "Message": "یک تسک با این عنوان قبلا در سیستم ثبت شده است", "MemberName": "Title", "Keywords": [ "Task", "UIX_Task_NormalizedTitle" ] } ], "DbException": "امکان ذخیرهسازی اطلاعات وجود ندارد؛ دوباره تلاش نمائید", "DbConcurrencyException": "اطلاعات توسط کاربری دیگر در شبکه تغییر کرده است", "InternalServerIssue": "متأسفانه مشکلی در فرآیند انجام درخواست شما پیش آمده است!" }
_session.UserId _session.UserId<long>() _session.UserId<int>() _session.UserId<Guid>()
public static class UserClaimTypes { public const string UserName = ClaimTypes.Name; public const string UserId = ClaimTypes.NameIdentifier; public const string SerialNumber = ClaimTypes.SerialNumber; public const string Role = ClaimTypes.Role; public const string DisplayName = nameof(DisplayName); public const string BranchId = nameof(BranchId); public const string BranchName = nameof(BranchName); public const string IsHeadOffice = nameof(IsHeadOffice); public const string TenantId = nameof(TenantId); public const string TenantName = nameof(TenantName); public const string IsHeadTenant = nameof(IsHeadTenant); public const string Permission = nameof(Permission); public const string PackedPermission = nameof(PackedPermission); public const string ImpersonatorUserId = nameof(ImpersonatorUserId); public const string ImpersonatorTenantId = nameof(ImpersonatorTenantId); }
/// <summary> /// Adds a file logger named 'File' to the factory. /// </summary> /// <param name="builder">The <see cref="ILoggingBuilder"/> to use.</param> public static ILoggingBuilder AddFile(this ILoggingBuilder builder) { builder.Services.AddSingleton<ILoggerProvider, FileLoggerProvider>(); return builder; } /// <summary> /// Adds a file logger named 'File' to the factory. /// </summary> /// <param name="builder">The <see cref="ILoggingBuilder"/> to use.</param> /// <param name="configure">Configure an instance of the <see cref="FileLoggerOptions" /> to set logging options</param> public static ILoggingBuilder AddFile(this ILoggingBuilder builder, Action<FileLoggerOptions> configure) { builder.AddFile(); builder.Services.Configure(configure); return builder; }
public interface ITenantResolutionStrategy { string TenantId(); } public interface ITenantStore { Task<Tenant> FindTenantAsync(string tenantId); }
public interface ITenantSession : IScopedDependency { /// <summary> /// Gets current TenantId or null. /// This TenantId should be the TenantId of the <see cref="IUserSession.UserId" />. /// It can be null if given <see cref="IUserSession.UserId" /> is a head-tenant user or no user logged in. /// </summary> string TenantId { get; } /// <summary> /// Gets current TenantName or null. /// This TenantName should be the TenantName of the <see cref="IUserSession.UserId" />. /// It can be null if given <see cref="IUserSession.UserId" /> is a head-tenant user or no user logged in. /// </summary> string TenantName { get; } /// <summary> /// Represents current tenant is head-tenant. /// </summary> bool IsHeadTenant { get; } /// <summary> /// TenantId of the impersonator. /// This is filled if a user with <see cref="IUserSession.ImpersonatorUserId" /> performing actions behalf of the /// <see cref="IUserSession.UserId" />. /// </summary> string ImpersonatorTenantId { get; } }
public static class SystemTime { public static Func<DateTime> Now = () => DateTime.UtcNow; public static Func<DateTime, DateTime> Normalize = (dateTime) => DateTime.SpecifyKind(dateTime, DateTimeKind.Utc); }
public interface IClock : ITransientDependency { DateTime Now { get; } DateTime Normalize(DateTime dateTime); } internal sealed class Clock : IClock { public DateTime Now => SystemTime.Now(); public DateTime Normalize(DateTime dateTime) { return SystemTime.Normalize(dateTime); } }
public class Result { private static readonly Result _ok = new Result(false, string.Empty); private readonly List<ValidationFailure> _failures; protected Result(bool failed, string message) : this(failed, message, Enumerable.Empty<ValidationFailure>()) { Failed = failed; Message = message; } protected Result(bool failed, string message, IEnumerable<ValidationFailure> failures) { Failed = failed; Message = message; _failures = failures.ToList(); } public bool Failed { get; } public string Message { get; } public IEnumerable<ValidationFailure> Failures => _failures.AsReadOnly(); [DebuggerStepThrough] public static Result Ok() => _ok; [DebuggerStepThrough] public static Result Fail(string message) { return new Result(true, message); } //... }
services.AddFramework() .WithModelValidation() .WithFluentValidation() .WithMemoryCache() .WithSecurityService() .WithBackgroundTaskQueue() .WithRandomNumber();
تغییرات کتابخانه DNTFrameworkCore.EFCore
public abstract class TrackableEntity<TKey> : Entity<TKey>, ITrackable where TKey : IEquatable<TKey> { [NotMapped] public TrackingState TrackingState { get; set; } [NotMapped] public ICollection<string> ModifiedProperties { get; set; } }
public static class ConfigurationBuilderExtensions { public static IConfigurationBuilder AddEFCore(this IConfigurationBuilder builder, IServiceProvider provider) { return builder.Add(new EFConfigurationSource(provider)); } }
protected DbContextCore(DbContextOptions options, IEnumerable<IHook> hooks) : base(options) { _hooks = hooks ?? throw new ArgumentNullException(nameof(hooks)); }
public void IgnoreHook(string hookName) { _ignoredHookList.Add(hookName); }
internal sealed class RowIntegrityHook : PostActionHook<IHasRowIntegrity> { public override string Name => HookNames.RowIntegrity; public override int Order => int.MaxValue; public override EntityState HookState => EntityState.Unchanged; protected override void Hook(IHasRowIntegrity entity, HookEntityMetadata metadata, IUnitOfWork uow) { metadata.Entry.Property(EFCore.Hash).CurrentValue = uow.EntityHash(entity); } }
//DbContextCore : IUnitOfWork public string EntityHash<TEntity>(TEntity entity) where TEntity : class { var row = Entry(entity).ToDictionary(p => p.Metadata.Name != EFCore.Hash && !p.Metadata.ValueGenerated.HasFlag(ValueGenerated.OnUpdate) && !p.Metadata.IsShadowProperty()); return EntityHash<TEntity>(row); } protected virtual string EntityHash<TEntity>(Dictionary<string, object> row) where TEntity : class { var json = JsonConvert.SerializeObject(row, Formatting.Indented); using (var hashAlgorithm = SHA256.Create()) { var byteValue = Encoding.UTF8.GetBytes(json); var byteHash = hashAlgorithm.ComputeHash(byteValue); return Convert.ToBase64String(byteHash); } }
IsTamperedAsync HasTamperedEntryAsync TamperedEntryListAsync
public const string CreatedDateTime = nameof(ICreationTracking.CreatedDateTime); public const string CreatedByUserId = nameof(CreatedByUserId); public const string CreatedByBrowserName = nameof(CreatedByBrowserName); public const string CreatedByIP = nameof(CreatedByIP); public const string ModifiedDateTime = nameof(IModificationTracking.ModifiedDateTime); public const string ModifiedByUserId = nameof(ModifiedByUserId); public const string ModifiedByBrowserName = nameof(ModifiedByBrowserName); public const string ModifiedByIP = nameof(ModifiedByIP);
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.NormalizeDateTime(); modelBuilder.NormalizeDecimalPrecision(precision: 20, scale: 6); base.OnModelCreating(modelBuilder); }
MigrateDbContext<TContext>(this IHost host)
services.AddEFCore<ProjectDbContext>() .WithTrackingHook<long>() .WithDeletedEntityHook() .WithRowIntegrityHook() .WithNumberingHook(options => { options.NumberedEntityMap[typeof(Task)] = new NumberedEntityOption { Prefix = "Task", FieldNames = new[] {nameof(Task.BranchId)} }; });
تغییرات کتابخانه DNTFrameworkCore.Web.Tenancy
services.AddTenancy() .WithTenantSession() .WithStore<InMemoryTenantStore>() .WithResolutionStrategy<HostResolutionStrategy>();
app.UseTenancy();
سایر کتابخانهها تغییرات خاصی نداشتند و صرفا نحوه معرفی سرویسهای آنها ممکن است تغییر کند و یا وابستگیهای آنها به آخرین نسخه موجود ارتقاء داده شده باشند که در پروژه DNTFrameworkCore.TestAPI اعمال شدهاند.
PM> Install-Package DNTFrameworkCore PM> Install-Package DNTFrameworkCore.EFCore PM> Install-Package DNTFrameworkCore.EFCore.SqlServer PM> Install-Package DNTFrameworkCore.Web PM> Install-Package DNTFrameworkCore.FluentValidation PM> Install-Package DNTFrameworkCore.Web.Tenancy PM> Install-Package DNTFrameworkCore.Licensing
نگاهی به آینده WebAssembly
The future of WebAssembly - A look at upcoming features and proposals
WebAssembly is a performance optimised virtual machine that was shipped in all four major browsers earlier this year. It is a nascent technology and the current version is very much an MVP (minimum viable product). This blog post takes a look at the WebAssembly roadmap and the features it might be gain in the near future.
I’ll try to keep this blog post relatively high-level, so I’ll skip over some of the more technical proposals, instead focusing on what they might mean for languages that target WebAssembly.
کتابخانه itoc.js
It is a jQuery plugin, A toc tree generator from html document.
تنظیمات JSON در ASP.NET Web API
new JsonSerializerSettings { Error = (sender, eventArgs) => { Debug.WriteLine(eventArgs.ErrorContext.Error.Message); //if an error happens we can mark it as handled, and it will continue eventArgs.ErrorContext.Handled = true; } }
نگاهی به Duende IdentityServer 5
Securing your application is bloody important. With so much jargon to sift through, it’s easy to get lost, for example there’s SSO, OAuth2, SAML 2.0, OpenID Connect, Federated Identity, 2FA, & MFA. Just to name a few! 😱 In this talk, Anthony will take an in depth look at Federated Identity using OpenID Connect and OAuth2 Framework for ASP. NET Core using Duende IdentityServer (aka IdentityServer 5). You will walk away knowing how to navigate the security options and avoid the madness.
مجموعهی مهندسی معکوس برای همه!
This comprehensive set of reverse engineering tutorials covers x86, x64 as well as 32-bit ARM and 64-bit architectures. If you're a newbie looking to learn reversing, or just someone looking to revise on some concepts, you're at the right place. As a beginner, these tutorials will carry you from nothing upto the mid-basics of reverse engineering, a skill that everyone within the realm of cyber-security should possess. If you're here just to refresh some concepts, you can conveniently use the side bar to take a look at the sections that has been covered so far.
You may have noticed it already, but when you create a console application with Visual Studio 2019, the default runtime is not .NET 5 but .NET Core 3.1! Why ? Because .NET 5 is not LTS and therefore Microsoft has intentionally chosen to offer the latest LTS version of .NET by default, ie .NET Core 3.1.