标签: clean-architecture

mongoDb数据库如何尊重清洁代码架构?

我正在设置一个 C# Asp.Net Core Api,它将在未来大幅增长。因此,我试图尊重干净代码架构,以我的域为中心,没有任何依赖性和周围的一切:

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

我目前正在实施存储库。我的问题是,对于 mongoDb,似乎必须提供属性[BsonId],或者在我的实体中使用 BsonId。但这意味着在我的实体项目中添加 mongoDb 引用,我不是它的忠实粉丝。

public interface IRepository<TDocument> where TDocument : Entity
{
    IQueryable<TDocument> AsQueryable();
    IEnumerable<TDocument> FilterBy(
        Expression<Func<TDocument, bool>> filterExpression);
    IEnumerable<TProjected> FilterBy<TProjected>(
        Expression<Func<TDocument, bool>> filterExpression,
        Expression<Func<TDocument, TProjected>> projectionExpression);
    Task<TDocument> FindOne(Expression<Func<TDocument, bool>> filterExpression);

    Task<TDocument> FindById(Guid id);
    Task InsertOne(TDocument document);
    Task InsertMany(ICollection<TDocument> documents);
    Task ReplaceOne(TDocument document);
    Task DeleteOne(Expression<Func<TDocument, bool>> filterExpression);
    Task DeleteById(Guid id);
    Task DeleteMany(Expression<Func<TDocument, bool>> filterExpression);
}
Run Code Online (Sandbox Code Playgroud)

在我在 Clean Architecture 上找到的示例中,他们大多使用实体框架,不需要绝对属性即可工作。 …

c# repository-pattern mongodb .net-core clean-architecture

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

使用 Asp.Net Core Identity 通过干净的架构进行授权和身份验证

我是第一次学习干净和垂直切片架构,如果我们使用 ASP.NET Core Identity,我很难理解授权和身份验证的适用范围。而且,在某些情况下,感觉将身份用户(使用用户名、密码、电子邮件等)与任何用户相关的域实体分开会很棘手。

例如,如果我们有一个使用 ASP.NET Core MVC、ASP.NET Core Identity 的解决方案,那么示例项目结构可能如下:

演示/WebUI 项目:

  • cshtml 视图/Razor 页面以及控制器(如果不使用 Razor 页面)将驻留在此处。
  • 该项目的program/startup.cs是可以调用其他层的扩展方法的地方:
app.services.InjectInfrastructure(); // same for application
Run Code Online (Sandbox Code Playgroud)

基础设施项目:

  • 应用层合约的实现。
  • 数据库上下文。
  • 如果您正在使用存储库,则可能是存储库的实现。

应用项目:

  • 命令/查询(假设使用 MassTransit.Mediator 或 MediatR 之类的东西)。
  • 验证器(例如使用流畅的验证)。

领域项目:

  • 领域实体(贫血或如果遵循 DDD,则使用方法)。
  • 任何聚合、值对象等(如果使用)。

因此,我们可以有一个具有以下流程的场景:

  1. 调用控制器操作来获取一些数据(表示应用程序层查询),该数据返回渲染的 html(cshtml 视图)。
  2. 数据填充在此 html 页面上,并将 POST 请求(表示应用程序层命令)发送到控制器操作。
  3. 命令或查询是使用 MediatR 发送的。
  4. 命令处理程序运行(使用 dbcontext 或存储库等数据访问),它会验证数据、对数据进行适当的更改并返回响应。
  5. 响应返回到控制器,然后控制器可以确定命令/查询是否成功
  6. 控制器重定向到另一个操作或填充 ModelState 错误。

我很难分离身份验证问题的情况是系统中的用户根据他们在登录时所做的选择具有不同的角色和权限。

例如,一个教育应用程序,教师可以选择他们当前代表的学校。在一所学校中,他们可能担任某种角色(例如校长),而在另一所学校中,他们可能担任特权较小的角色。

在这样的场景中,角色、应用程序用户(都是身份问题)似乎与域(将容纳不同的学校和每个学校拥有的角色)紧密耦合。

我的首要问题是,我们如何以干净的架构方式使用 ASP.NET 身份来实现这种身份验证/授权场景?

目前这种情况带来了多个问题:

  1. 如果我们要将身份验证/授权与表示层解耦,则不能依赖控制器上的 [Authorize(Role = "X")] [Authorize(Policy = "Y")] 装饰器,因为此逻辑应委托给基础设施(以确保如果我们想在任何时候交换表示层,我们不需要重写身份验证/授权)
  2. 此场景中的用户与域逻辑紧密耦合,因此只有在身份相关实体和域实体被压缩在单个 dbContext 中时我才能看到它工作

有没有人曾经遇到过/使用干净的架构实现过这样的系统?任何人对此有任何见解都会很棒!

asp.net-mvc asp.net-identity asp.net-core clean-architecture

5
推荐指数
0
解决办法
2089
查看次数

Room Entity 和 Clean 架构 Domain 层的 Entity 是否不同?

我的问题如标题所示。

Room 有注释@Entity,在 Room 中,这被视为Entity.
但在 Clean 架构中,当使用 Domain 层时,Entity也会使用 an。
例如,领域层内的用例使用的实体。
然而,我认为 Room 认为的Entity是 Clean 架构的 aDTOPOJOas。

话虽如此,在创建应用程序时,我应该在表示层、领域层和数据层中为我的模型命名什么?

android entity kotlin clean-architecture android-room

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

“面向对象编程对间接控制转移施加纪律”是什么意思?

我最近读完了 Unckle Bob 的《Clean Architecture》一书。他在那里写道

三个范式。三个约束。结构化编程对直接控制转移施加了纪律。面向对象编程对间接控制转移施加了纪律。函数式编程对分配施加纪律。这些范式中的每一个都带走了一些东西。他们都没有添加任何新功能。每一次都增加了纪律并降低了能力。

  1. 间接控制权转移是什么意思?
  2. OOP中是如何限制的?

oop clean-architecture

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

您可以在具有简洁架构的功能之间共享模型吗?

我的应用程序具有以下文件夹结构

app
    core
    features
        feature1
            domain
                entities
                    entity1
                    entity2
                    entity3
                    entity4
                    entity5
                    entity6
            data
                models
                    model1
                    model2
                    model3
                    model4
                    model5
                    model6
            presentation
        feature2
            domain
                entities
                    entity1
                    entity2
                    entity3
                    entity4
                    entity5
                    entity6
            data
                models
                    model1
                    model2
                    model3
                    model4
                    model5
                    model6
            presentation
Run Code Online (Sandbox Code Playgroud)

这两个功能的模型 1 到 6 完全相同,并且随着应用程序的扩展,还会有更多功能出现。这变得越来越难以维护。干净的架构是否允许跨多个功能共享模型和实体?这是通过核心文件夹完成的吗?

flutter clean-architecture

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

“dagger.hilt.android.internal.lifecycle.DefaultActivityViewModelFactory”无法解析

我花了一周的时间试图将 hilt 依赖注入添加到我的示例笔记应用程序中,android studio 在发生错误后一直向我抛出错误。无论如何,这让我很生气,因为 AppModule我一直在尝试将我的房间数据库注入到应用程序中存储库,然后我的应用程序存储库到我的用例类,最后将用例类注入到我的用例类中sharedViewModel ,所以这是我的AppModule对象:

@Module
@InstallIn(SingletonComponent::class)
object AppModule {

    @Provides
    @Singleton
    fun provideNoteDatabase(app: Application): NoteDatabase {
        return Room.databaseBuilder(
            app,
            NoteDatabase::class.java,
            NoteDatabase.DATABASE_NAME
        ).build()
    }

    @Provides
    @Singleton
    fun provideNoteRepository(db: NoteDatabase): NotesRepo {
        return RepoImplementation(db.noteDao())
    }

    @Provides
    @Singleton
    fun provideNoteUseCase(repo: NotesRepo): NoteUseCase {
        return NoteUseCase(
            getNotesUseCase = GetNotesUseCase(repo),
            deleteNoteUseCase = DeleteNoteUseCase(repo),
            updateNoteUseCase = UpdateNoteUseCase(repo),
            insertNoteUseCase = InsertNoteUseCase(repo)
        )
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我的应用程序类:

@HiltAndroidApp
class Application : Application()
Run Code Online (Sandbox Code Playgroud)

我的编辑片段:

@AndroidEntryPoint
class EditFragment : Fragment() {

    private var _binding: …
Run Code Online (Sandbox Code Playgroud)

android mvvm kotlin clean-architecture dagger-hilt

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

Android多模块架构:领域取决于数据,反之亦然

一些Android多模块架构示例表明领域层依赖于数据。其他人则相反。

\n

Android 开发者网站说:

\n
\n

领域层是位于 UI 层和数据层之间的可选层。

\n
\n

它还显示了域依赖于数据的图片:\n域取决于数据

\n

与此同时,proandroiddev.com 上的另一篇文章说:

\n

1.

\n
\n

域层\xc2\xa0是洋葱的最内部部分(与其他层没有依赖关系),它包含\xc2\xa0实体、用例和存储库接口。\xc2\xa0用例组合来自1个或多个存储库接口的数据。

\n
\n
    \n
  1. \n
\n
\n

最常见的错误之一是让您的应用程序由数据层/特定数据系统驱动。

\n
\n
    \n
  1. \n
\n
\n

域层不依赖于数据层。

\n
\n

并显示适当的图像:\n在此输入图像描述

\n

那么您能否描述一下哪种方法更适合 Android 多模块?为什么?

\n

architecture android clean-architecture android-architecture android-multi-module

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

在RxJava上使用Android上的干净MVP:如何在仍然观察UI线程的同时保持演示者没有任何Android知识?

为了在Android上使用mvp模式实现"干净"架构,建议将android框架视为插件,而不是将任何知识产权感知依赖项泄漏到演示者层.使用rxjava,如果我有一个用于将数据"推送"到视图层的演示者,我可能希望有这样的逻辑:

public interface SearchPresenter {

  interface ViewLayer {
  void updateResults(List<SearchResult> searchResults)
  }
  void bind(ViewLayer viewLayer);
  void unbind();
}

public class SearchPresenterImpl implements SearchPresenter {

   ViewLayer viewLayer;
   CompositeDisposable compositeDisposable;

    @Override
    public void bind(ViewLayer viewLayer) {
      this.viewLayer = viewLayer;

      compositeDisposable = new CompositeDisposable();
      compositeDisposable.add(
            searchInteractor.getSearchResults()
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(this::refreshView));

}

private void refreshView(List<SearchResult> searchResults) {
    //send the results back to the view layer to update a RecyclerView      
    viewLayer.updateResults(searchResults)
}

@Override
public void unbind() {
    compositeDisposable.dispose();
}
Run Code Online (Sandbox Code Playgroud)

但是,通过观察'AndroidSchedulers.mainThread()',这会强制依赖于:

import io.reactivex.android.schedulers.AndroidSchedulers
Run Code Online (Sandbox Code Playgroud)

在这一点上,我的主持人现在知道android并且与之相关; 我想避免.

处理这个的建议方法是什么,以保证结果在Android的UI(主)线程上传递给ViewLayer,而演示者维护没有任何与Android相关的依赖?

android rx-java clean-architecture android-mvp

4
推荐指数
1
解决办法
1027
查看次数

在这种情况下,为什么处理DisposableObserver很重要

我正在使用干净的架构开发android项目.我有以下课程:

    public abstract class RxBaseInteractor<T, Params> {

  private final CompositeDisposable disposables;

  public RxBaseInteractor() {
    this.disposables = new CompositeDisposable();
  }

  abstract public Observable<T> buildUseCaseObservable(Params params);

  public void execute(DisposableObserver<T> observer, Params params) {
    Preconditions.checkNotNull(observer);
    final Observable<T> observable = this.buildUseCaseObservable(params)
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread());
    addDisposable(observable.subscribeWith(observer));
  }

  public void dispose() {
    if (!disposables.isDisposed()) {
      disposables.dispose();
    }
  }

  protected void addDisposable(Disposable disposable) {
    Preconditions.checkNotNull(disposable);
    Preconditions.checkNotNull(disposables);
    disposables.add(disposable);
  }
}
Run Code Online (Sandbox Code Playgroud)

所以执行(..)获取DisposableObserver然后有一个dispose()方法被调用来处理这个observable.

在我的例子中,observable可能来自WebApi使用Realm进行改造或缓存.

现在在演示者onDestroy()中,我调用了interactor.dispose(),如:

 @Override public void destroy() {
        super.destroy();
        myInteractor.dispose();
    }
Run Code Online (Sandbox Code Playgroud)

从视图中调用之后调用:

    @Override public void onDestroy() {
    super.onDestroy();
    if …
Run Code Online (Sandbox Code Playgroud)

android dispose observable rx-java clean-architecture

4
推荐指数
1
解决办法
2411
查看次数

在干净的 MVP 中,谁应该处理组合交互器?

我已经看到了 MVP 架构的好例子(这里这里)。两者都只提供简单的交互器,但我想知道如何处理更复杂的用例,包括在其他用例中重复的步骤。

例如,我的 API 需要令牌来验证任何调用。我创建了一个交互器来获取该令牌 ( GetToken)。我想获取用户的上次登录日期 ( GetLastLoginDate),然后获取该日期和现在 ( GetVersionChanges)之间发生的更改列表。

那些交互者应该被链接在哪里?我想将它们分开,因为其中一些在代码的其他部分被重用。我想出了两个解决方案。

  1. 演示者应该链接所有交互者。只要用例不复杂并且没有很多先决条件,这个解决方案就可以工作。在我看来,这不是正确的地方,因为它给演示者带来了另一项责任。

  2. Interactor 可以使用许多存储库(那时没有破坏干净的架构规则)。为什么不在TokenRepository其他交互器中使用?因为获取令牌比到达存储库要复杂得多。在其他交互器中重复这些步骤不会重用已经存在的代码。

这两种解决方案都有其缺陷,并且都违反了基本原则(DRY,单一职责原则)。

mvp android use-case clean-architecture

4
推荐指数
1
解决办法
2750
查看次数