2

When using Clean Architecture in Mvc Core, Layer with Name can be like this:

  1. Infrastructure
  2. Core
  3. Web

This link has complete description about that:

https://learn.microsoft.com/en-us/dotnet/standard/modern-web-apps-azure-architecture/common-web-application-architectures

Principles says that Web project shouldn't have any reference from Infrastructure class library. So how can use a DI container to resolve the problem?

This code in Startup.cs uses Infrastructure to config some things:

public void ConfigureProductionServices(IServiceCollection services)
{
    services.AddDbContext<CatalogContext>(c =>
    {
        try
        {
            c.UseSqlServer(Configuration.GetConnectionString("CatalogConnection"));
        }
        catch (Exception ex)
        {
            var message = ex.Message;
        }
    });

    services.AddDbContext<AppIdentityDbContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("CatalogConnection")));

    ConfigureServices(services);
}

public void ConfigureServices(IServiceCollection services)
{
    services.AddIdentity<ApplicationUser, IdentityRole>()
        .AddEntityFrameworkStores<AppIdentityDbContext>()
        .AddDefaultTokenProviders();

    services.AddScoped(typeof(IRepository<>), typeof(EfRepository<>));
    .
    .
    _services = services;
}
NightOwl888
  • 55,572
  • 24
  • 139
  • 212
Jourmand
  • 888
  • 10
  • 27
  • 1
    "Principles says that Infrastructure shouldn't have any reference to Infrastructure class library." -- can you cite where in the article it states that? From your code sample, it not clear exactly what what problem are you facing? – Jasen Feb 03 '18 at 22:07
  • @Jasen its mistake, I edited – Jourmand Feb 03 '18 at 22:13
  • So if you're concerned you can't wire-up the DI container (in the Web project) without a reference to the Infrastructure project -- don't worry. DI registration in the Composition Root will need these references -- just don't have the rest of the Web project interact with the Infrastructure directly -- this can be mitigated by not using the Infrastructure namespaces in the Web code. See this related question with many explanations https://stackoverflow.com/questions/5267525/dal-bll-gui-composition-root-how-to-setup-di-bindings – Jasen Feb 03 '18 at 22:20
  • @Jasen I hope so, But at that's link, there was a Note that say: In order to wire up dependency injection in ConfigureServices in the Startup.cs file of the UI project, the project may need to reference the Infrastructure project. This dependency can be eliminated, most easily by using a custom DI container. For the purposes of this sample, the simplest approach is to allow the UI project to reference the Infrastructure project. !!! – Jourmand Feb 03 '18 at 22:38
  • 1
    The DI Composition Root needs the reference. The Composition Root, in this case, exists in the Web project -- Go ahead and add the references (for DI registration). Do not have actual Web UI code reference the Infrastructure directly. – Jasen Feb 03 '18 at 22:42
  • @Jasen see this link: https://ardalis.com/avoid-referencing-infrastructure-in-visual-studio-solutions – Jourmand Feb 03 '18 at 22:52
  • I don't agree. But I understand the motivation for doing such a thing. – Jasen Feb 03 '18 at 22:56

1 Answers1

1

You say:

Principles says that Web project shouldn't have any reference from Infrastructure class library. So how can use a DI container to resolve the problem?

But the article you linked says:

enter image description here

Note that the solid arrows represent compile-time dependencies, while the dashed arrow represents a runtime-only dependency. Using the clean architecture, the UI layer works with interfaces defined in the Application Core at compile time, and ideally should not have any knowledge of the implementation types defined in the Infrastructure layer. At runtime, however, these implementation types will be required for the app to execute, so they will need to be present and wired up to the Application Core interfaces via dependency injection.

What the article is describing is the logical architecture of the application as opposed to the physical architecture of the application. Logically, the user interface knows nothing about the Infrastructure layer, but physically it is the DI code at application startup in the User Interface layer (right at the very beginning of the application at runtime) that composes the application components together. This concept can be illustrated and explained best here.

The idea is that we can use assemblies independently of one another without dragging along additional dependencies. In practice makes unit and integration testing easier and more reliable to do.

NightOwl888
  • 55,572
  • 24
  • 139
  • 212
  • 1
    That's true, but see @Steve Smith post that wrote solution for mvc 5. he use StructureMap, I'm doing so but Startup configuration stopped me: https://ardalis.com/avoid-referencing-infrastructure-in-visual-studio-solutions – Jourmand Feb 04 '18 at 00:31
  • Putting a StructureMap registry *in the component that uses it* is not a very practical approach. If you want to replace one of the Infrastructure components with one from LibraryX, Infastructure needs a project reference to LibraryX to pull this off. See the problem? We don't want our assemblies knowing about each other like this so they can be used in other contexts without dragging along unnecessary dependencies. – NightOwl888 Feb 04 '18 at 00:40