小编Gur*_*ler的帖子

使用 EF Core 正确实现存储库模式

笔记

我没有问,如果我要使用Repository模式,我关心的如何。将与持久性相关的对象注入域类对我来说不是一个选择:它使单元测试变得不可能(不,使用内存数据库的测试不是单元测试,因为它们没有隔离地覆盖了许多不同的类),它耦合了域逻辑使用 ORM,它打破了我实践的许多重要原则,例如持久性无知、关注点分离等,欢迎您在线搜索它们的好处。对我来说,“正确”使用 EF Core 并不像保持业务逻辑与外部问题的隔离那么重要,这就是为什么我会接受 EF Core 的“hacky”使用,如果这意味着存储库不会泄漏不再抽象。

原始问题

让我们假设存储库的界面如下:

public interface IRepository<TEntity>
    where TEntity : Entity
{
    void Add(TEntity entity);
    void Remove(TEntity entity);
    Task<TEntity?> FindByIdAsync(Guid id);
}

public abstract class Entity
{
    public Entity(Guid id)
    {
        Id = id;
    }
    public Guid Id { get; }
}
Run Code Online (Sandbox Code Playgroud)

我在网上看到的大多数 EF Core 实现都做了类似的事情:

public class EFCoreRepository<TEntity> : IRepository<TEntity>
    where TEntity : Entity
{
    private readonly DbSet<TEntity> entities;

    public EFCoreRepository(DbContext dbContext)
    {
        entities = dbContext.Set<TEntity>();
    }

    public …
Run Code Online (Sandbox Code Playgroud)

c# domain-driven-design ddd-repositories repository-pattern entity-framework-core

11
推荐指数
2
解决办法
1977
查看次数

如何在C#中缓存具有多个键的对象

我有2个或更多属性唯一的模型。例如,该类的对象在Entity名称和ID上都是唯一的。

public class Entity
{
    public int Id { get; set; }
    public string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我有一个模型存储库:

public class EntityRepository
{
    ...
    public Entity GetById(int id)
    {
        return db.GetById(id);
    }
    public Entity GetByName(string name)
    {
        return db.GetByName(name);
    }
}
Run Code Online (Sandbox Code Playgroud)

什么是缓存到两个呼叫的最佳方式GetById,并呼吁GetByName使用Microsoft.Extensions.Caching.Memory.IMemoryCache

当前解决方案:

public class EntityRepository
{
    ...
    public Entity GetById(int id)
    {
        return Cache.GetOrCreate($"id:{id}", cacheEntry =>
        {
            return db.GetById(id);
        });
    }
    public Entity GetByName(string name)
    {
        return Cache.GetOrCreate($"name:{name}", cacheEntry …
Run Code Online (Sandbox Code Playgroud)

c# caching memorycache .net-core asp.net-core

5
推荐指数
1
解决办法
62
查看次数

如何测试 DDD 命令处理程序中的逻辑?

我正在尝试学习 DDD 和 Clean Architecture 的一些想法,但遇到了一个问题:如何对应用程序层中的命令处理程序进行单元测试,验证它们在域对象上调用正确的方法,而不测试内部的逻辑那些域对象?假设我有以下域实体:

public class User
{
    public User(int id)
    {
        Id = id;
    }

    public int Id { get; }

    public void RemoveProfilePicture()
    {
        ...
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

我有以下简单的命令类:

public class RemoveUserProfilePictureCommand : ICommand
{
    public RemoveUserProfilePictureCommand(int userId)
    {
        UserId = userId;
    }
    public int UserId { get; }
}
Run Code Online (Sandbox Code Playgroud)

和命令处理程序(位于应用程序层):

public class Handler : ICommandHandler<RemoveUserProfilePictureCommand>
{
    private readonly IUserRepository userRepository;

    public Handler(IUserRepository userRepository)
    {
        this.userRepository = userRepository;
    }

    public void Handle(RemoveUserProfilePictureCommand command)
    {
        var user …
Run Code Online (Sandbox Code Playgroud)

c# unit-testing domain-driven-design clean-architecture

5
推荐指数
1
解决办法
1290
查看次数

ASP.NET Core 的 DI 容器是否保证服务的顺序?

当我用同一个接口向DI容器注册多个服务然后请求一个时IEnumerable<IService>,容器是否保证注册的顺序就是集合的顺序?因为这似乎是行为,但我在文档中找不到任何关于它的信息。

示例 - 假设我们有这个接口:

public interface IStep
{
    void Execute();
}
Run Code Online (Sandbox Code Playgroud)

以及一些实现:

public class FirstStep : IStep { ... }
public class SecondStep : IStep { ... }
public class ThirdStep : IStep { ... }
...
Run Code Online (Sandbox Code Playgroud)

我们将它们注册到容器中:

services.AddTransient<IStep, FirstStep>();
services.AddTransient<IStep, SecondStep>();
services.AddTransient<IStep, ThirdStep>();
Run Code Online (Sandbox Code Playgroud)

最后请求一个集合IStep

public class Plan
{
    private readonly IEnumerable<IStep> steps;

    public Plan(IEnumerable<IStep> steps)
    {
        this.steps = steps;
    }

    public void Execute()
    {
        foreach (var step in steps)
        {
            step.Execute();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

假设步骤将根据注册顺序执行是否可以?如果不是,那么实现类似管道行为的最佳方法是什么?

c# dependency-injection .net-core asp.net-core

2
推荐指数
2
解决办法
1579
查看次数