This project is the next generation of the ASP.NET Boilerplate web application framework.
Modular Architecture
Designed as modular and extensible from the bottom to the top.
Microservice Focused
Designed to support microservice architecture and helps to build autonomous microservices.
Domain Driven Design
Designed and developed based on DDD patterns and principles. Provides a layered model for your application.
Authorization
Advanced authorization with user, role and fine-grained permission system. Built on the Microsoft Identity library.
Multi-Tenancy
SaaS applications made easy! Integrated multi-tenancy from database to UI.
Cross Cutting Concerns
Complete infrastructure for authorization, validation, exception handling, caching, audit logging, transaction management and so on.
LINQ Extensions Library - Pivot Extensions
The pivot feature enables transforming a collection of objects into a new collection of objects flattening the original hierarchy
: In the following example The Pivot extension method is used to transform a collection as follow
دوره آموزشی Blazor
Welcome to this short introduction to Blazor! This new Microsoft framework uses a unique approach to leverage your existing C# and .NET skills to create single-page applications running in web browsers. The technology that makes this possible is called WebAssembly, an open standard supported directly by current browsers on desktop and mobile platforms. You write C# and Razor code instead of JavaScript, and the compiled app runs natively on the client.
Sample Source Code: https://github.com/DevExpress/blazor-training-samples
بازگشت مجدد API استاتیک AutoMapper
public class PostDto : BaseDto<PostDto, Post, long> { public string Title { get; set; } public string Text { get; set; } public int CategoryId { get; set; } public string CategoryName { get; set; } //=> Category.Name }
- کلاس PostDto خودش را به عنوان اولین پارامتر جنریک BaseDto معرفی میکند.
- به عنوان پارامتر دوم، باید کلاس Entity ایی که قرار است به آن نگاشت شود (Post) را معرفی کنیم.
- پارامتر سوم، نوع فیلد Id است که در اینجا خاصیت Id کلاسهای Post و PostDto ما، از نوع long است.
- نهایتا خواصی را که برای نگاشت لازم داریم، تعریف میکنیم مثل Title و...
- همچنین میتوانیم خواصی برای نگاشت با خواص Navigation Propertyهای Post هم تعریف کنیم؛ مانند CategoryName که به خاصیت Name از Category پست مربوطه اشاره میکند و AutoMapper به صورت هوشمندانه آنها را به هم نگاشت میکند.
public abstract class BaseDto<TDto, TEntity, TKey> where TDto : class, new() where TEntity : BaseEntity<TKey>, new() { [Display(Name = "ردیف")] public TKey Id { get; set; } public TEntity ToEntity() { return Mapper.Map<TEntity>(CastToDerivedClass(this)); } public TEntity ToEntity(TEntity entity) { return Mapper.Map(CastToDerivedClass(this), entity); } public static TDto FromEntity(TEntity model) { return Mapper.Map<TDto>(model); } protected TDto CastToDerivedClass(BaseDto<TDto, TEntity, TKey> baseInstance) { return Mapper.Map<TDto>(baseInstance); } }
- نوع TDto به کلاس Dto ما اشاره میکند؛ مثلا PostDto
- نوع TEntity به کلاس Entity ما اشاره میکند؛ مثلا Post
- نوع TKey به نوع خاصیت Id اشاره میکند.
- شرط لازم برای نوع TEntity این است که از <BaseEntity<TKey ارث بری کرده باشد (نوع پایهای که تمام Entityهای ما از آن ارث بری میکنند).
- متدهای کمکی ToEntity و FromEntity، کار نگاشت اشیاء را برای ما راحتتر میکنند.
public abstract class BaseEntity<TKey> { public TKey Id { get; set; } } public class Post : BaseEntity<long> { public string Title { get; set; } public string Text { get; set; } public int CatgeoryId { get; set; } public Category Category { get; set; } }
var postDto = new PostDto(); var post = postDto.ToEntity();
var post = // finded by id var updatePost = postDto.ToEntity(post);
var postDto = PostDto.FromEntity(post);
public static class AutoMapperConfiguration { public static void InitializeAutoMapper() { Mapper.Initialize(configuration => { configuration.ConfigureAutoMapperForDto(); }); //Compile mapping after configuration to boost map speed Mapper.Configuration.CompileMappings(); } public static void ConfigureAutoMapperForDto(this IMapperConfigurationExpression config) { config.ConfigureAutoMapperForDto(Assembly.GetEntryAssembly()); } public static void ConfigureAutoMapperForDto(this IMapperConfigurationExpression config, params Assembly[] assemblies) { var dtoTypes = GetDtoTypes(assemblies); var mappingTypes = dtoTypes .Select(type => { var arguments = type.BaseType.GetGenericArguments(); return new { DtoType = arguments[0], EntityType = arguments[1] }; }).ToList(); foreach (var mappingType in mappingTypes) config.CreateMappingAndIgnoreUnmappedProperties(mappingType.EntityType, mappingType.DtoType); } public static void CreateMappingAndIgnoreUnmappedProperties(this IMapperConfigurationExpression config, Type entityType, Type dtoType) { var mappingExpression = config.CreateMap(entityType, dtoType).ReverseMap(); //Ignore mapping to any property of source (like Post.Categroy) that dose not contains in destination (like PostDto) //To prevent from wrong mapping. for example in mapping of "PostDto -> Post", automapper create a new instance for Category (with null catgeoryName) because we have CategoryName property that has null value foreach (var property in entityType.GetProperties()) { if (dtoType.GetProperty(property.Name) == null) mappingExpression.ForMember(property.Name, opt => opt.Ignore()); } } public static IEnumerable<Type> GetDtoTypes(params Assembly[] assemblies) { var allTypes = assemblies.SelectMany(a => a.ExportedTypes); var dtoTypes = allTypes.Where(type => type.IsClass && !type.IsAbstract && type.BaseType != null && type.BaseType.IsGenericType && (type.BaseType.GetGenericTypeDefinition() == typeof(BaseDto<,>) || type.BaseType.GetGenericTypeDefinition() == typeof(BaseDto<,,>))); return dtoTypes; } }
public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; AutoMapperConfiguration.InitializeAutoMapper(); }
public static IEnumerable<Type> GetDtoTypes(params Assembly[] assemblies) { var allTypes = assemblies.SelectMany(a => a.ExportedTypes); var dtoTypes = allTypes.Where(type => type.IsClass && !type.IsAbstract && type.BaseType != null && type.BaseType.IsGenericType && (type.BaseType.GetGenericTypeDefinition() == typeof(BaseDto<,>) || type.BaseType.GetGenericTypeDefinition() == typeof(BaseDto<,,>))); return dtoTypes; }
- در خط اول ابتدا تمامی نوعهای قابل دسترس از بیرون (ExportedTypes) از assemblyهای دریافتی واکشی میشود.
- سپس توسط Where، نوعهایی که کلاس بوده، abstract نیستند و از BaseDto ارث بری کردهاند، فیلتر شده و بازگردانده میشوند.
public static void ConfigureAutoMapperForDto(this IMapperConfigurationExpression config, params Assembly[] assemblies) { var dtoTypes = GetDtoTypes(assemblies); var mappingTypes = dtoTypes .Select(type => { var arguments = type.BaseType.GetGenericArguments(); return new { DtoType = arguments[0], EntityType = arguments[1] }; }).ToList(); foreach (var mappingType in mappingTypes) config.CreateMappingAndIgnoreUnmappedProperties(mappingType.EntityType, mappingType.DtoType); }
public static void CreateMappingAndIgnoreUnmappedProperties(this IMapperConfigurationExpression config, Type entityType, Type dtoType) { var mappingExpression = config.CreateMap(entityType, dtoType).ReverseMap(); //Ignore mapping to any property of entity (like Post.Categroy) that dose not contains in dto (like PostDto.CategoryName) //To prevent from wrong mapping. for example in mapping of "PostDto -> Post", automapper create a new instance for Category (with null catgeoryName) because we have CategoryName property that has null value foreach (var property in entityType.GetProperties()) { if (dtoType.GetProperty(property.Name) == null) mappingExpression.ForMember(property.Name, opt => opt.Ignore()); } }
کتابخانه easystarjs
- Calculates asynchronously for better overall performance
- Simple API
- Small. ~5kb
- Use it with any existing Javascript Framework
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
D3 6.0 منتشر شد
D3 6.0: The Data-Driven Document Library — The popular data visualization library takes a step forward by switching out a few internal dependencies for better alternatives, adopts ES2015 (a.k.a. ES6) internally, and now passes events directly to listeners. There’s also a 5.x to 6.0 migration guide for existing users.