為什么不自己做購物網站承接婚慶公司網站建設
鶴壁市浩天電氣有限公司
2026/01/24 09:15:34
為什么不自己做購物網站,承接婚慶公司網站建設,手繪動畫制作軟件,wordpress手機版怎么用一、充血模型和失血模型1. 充血模型的優(yōu)勢充血模型更加OOP充血模型代碼可讀性更好1.1 充血模型偽代碼var messageDto controller.ReadDto();var message messageDto.ToEntity();message.Save();1.2 失血模型偽代碼var messageDto controller.ReadDto();var message message…一、充血模型和失血模型1. 充血模型的優(yōu)勢充血模型更加OOP充血模型代碼可讀性更好1.1 充血模型偽代碼var messageDto controller.ReadDto();var message messageDto.ToEntity();message.Save();1.2 失血模型偽代碼var messageDto controller.ReadDto();var message messageDto.ToEntity();var messageService controller.GetMessageService();messageService.Save(message);2. 充血模型愛你不容易大部分程序員都知道充血模型好,想實現卻很難大部分業(yè)務邏輯都需要依賴外部服務充血模型需要用到外部服務,又不想依賴外部服務的具體實現很容易想到使用IOC的依賴注入來解決我們給DTO注入服務還行,因為IOC參與了controller過程當DTO發(fā)生轉化時,新增的服務IOC還是有點力不從心沒法引用外部服務的充血模型氣血不通,業(yè)務表達能力大大下降這也是大部分人棄用充血模型的主要原因,不好用還不如不用這個任督二脈PocoEmit可以幫你打通二、首先來個Case演示一下Dto轉化為實體但是實體有更多邏輯依賴外部服務,這些外部服務Dto不見得提供的了這就需要注入PocoEmit支持構造函數參數注入和屬性注入IMapper對象是默認支持注入的服務1. Entity比Dto多出來的Mapper可以注入class MessageDto{public string Message { get; set; }}class MessageEntity{public IMapper Mapper { get; set; }public string Message { get; set; }}2. 轉化并注入的代碼var mapper Mapper.Create();var dto new MessageDto { Message Hello UseMapper };MessageEntity message mapper.ConvertMessageDto, MessageEntity(dto);Assert.NotNull(message.Mapper);三、再演示注入自定義的服務1. UserDomain比Dto多出來的Repository可以注入class UserDTO{public int Id { get; set; }public string Name { get; set; }}class UserDomain(UserRepository repository, int id, string name){private readonly UserRepository _repository repository;public UserRepository Repository _repository;public int Id { get; } id;public string Name { get; } name;// ...}class UserRepository{void Add(UserDomain user) { }void Update(UserDomain entity) { }void Remove(UserDomain entity) { }public static readonly UserRepository Instance new();}2. 注冊、轉化并注入的代碼通過UseDefault可以注入服務IMapper mapper Mapper.Create().UseDefault(UserRepository.Instance);var dto new UserDTO { Id 1, Name Jxj };UserDomain user mapper.ConvertUserDTO, UserDomain(dto);Assert.NotNull(user.Repository);四、注入IOC容器的Case注入IOC容器需要安裝nuget包PocoEmit.ServiceProvider1. 包含IOC容器的實體class UserWithServiceProvider{public int Id { get; set; }public string Name { get; set; }public IServiceProvider ServiceProvider { get; set; }}2. 注冊、轉化并注入的代碼UseSingleton是把容器作為唯一容器注入UseScope是使用當前Scope子容器UseContext是在Mvc下,使用當前HttpContext的RequestServices子容器var services new ServiceCollection();var serviceProvider services.BuildServiceProvider();var mapper Mapper.Create();mapper.UseSingleton(serviceProvider);var dto new UserDTO { Id 1, Name Jxj };UserWithServiceProvider user mapper.ConvertUserDTO, UserWithServiceProvider(dto);Assert.NotNull(user.ServiceProvider);五、當然還可以注入容器內的服務1. UserDomain多出來的Repository需要注入這次我們用IOC來管理Repository這樣才能更好的利用依賴注入Repository可能還會依賴其他的服務手動維護服務對象可能會很麻煩,IOC容器擅長維護這些復雜關系class UserDomain(UserRepository repository, int id, string name){private readonly UserRepository _repository repository;public UserRepository Repository _repository;public int Id { get; } id;public string Name { get; } name;// ...}class UserRepository{void Add(UserDomain user) { }void Update(UserDomain entity) { }void Remove(UserDomain entity) { }}2. 注冊、轉化并注入的代碼通過UseScope注入IOC容器通過UseDefault告知這個類型從IOC容器中注入var services new ServiceCollection().AddScopedUserRepository();var serviceProvider services.BuildServiceProvider();var mapper Mapper.Create();mapper.UseScope(serviceProvider).UseDefaultUserRepository();var dto new UserDTO { Id 1, Name Jxj };UserDomain user mapper.ConvertUserDTO, UserDomain(dto);Assert.NotNull(user.Repository);六、支持IOC容器的特性支持FromKeyedServices支持FromServices1. FromKeyedServices標記注入點和服務鍵class UserDomain1([FromKeyedServices(User1)]UserRepository repository, int id, string name): UserDomain(repository, id, name){}class UserDomain2([FromKeyedServices(User2)] UserRepository repository, int id, string name): UserDomain(repository, id, name){}class UserDomain(UserRepository repository, int id, string name){private readonly UserRepository _repository repository;public UserRepository Repository _repository;public int Id { get; } id;public string Name { get; } name;// ...}class UserRepository(string tableName){private readonly string _tableName tableName;public string TableName _tableName;void Add(UserDomain user) { }void Update(UserDomain entity) { }void Remove(UserDomain entity) { }}2. 注冊、轉化并注入的代碼由于識別出FromKeyedServices,就不需要UseDefault這樣簡潔又優(yōu)雅string table1 User1;string table2 User2;var services new ServiceCollection().AddKeyedScoped(table1, (_, _) new UserRepository(table1)).AddKeyedScoped(table2, (_, _) new UserRepository(table2));var serviceProvider services.BuildServiceProvider();var mapper Mapper.Create();mapper.UseScope(serviceProvider);var dto new UserDTO { Id 1, Name Jxj };UserDomain user mapper.ConvertUserDTO, UserDomain1(dto);Assert.NotNull(user.Repository);UserDomain user2 mapper.ConvertUserDTO, UserDomain2(dto);Assert.NotNull(user2.Repository);七、競品類似的功能1. AutoMapper不支持AutoMapper的NullSubstitute用來指定源屬性為null時的默認值用AutoMapper實現類似功能需要復雜的自定義IValueResolver來實現PocoEmit在源無法匹配或源字段為null都可能觸發(fā)依賴注入2. EF有類似功能不過貌似只支持EF內部某些服務請參閱 EF Core實體類的依賴注入八、總結1. OOM映射需要依賴注入DTO、實體、領域模型如果有業(yè)務邏輯就需要依賴外部服務支持按類型注入,也支持按指定的參數或屬性注入支持FromKeyedServices和FromServices需要外部服務就需要依賴注入2. PocoEmit的依賴注入助力程序分層架構依賴注入的加持每一層想調用啥就調用啥同時也讓每一層更好的劃分讓調用啥,不讓調用啥更容易控制同時也讓業(yè)務需要劃分多少層就劃分多層變得簡單3. IOC容器使用需要注意簡單作業(yè)單容器,使用UseSingleton即可多線程需要使用UseScopeMvc(含WebApi)邏輯處理使用UseContextUseContext需要引用nuget包PocoEmit.Mvc如果是Mvc異步處理或Quartz類似作業(yè)不要用UseContext就怕異步中獲取到了HttpContext,但執(zhí)行中途被釋放了,后面就可能異常了