Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Abstract Factory and Onion Architecture solve different problems: Onion Architecture controls the direction of code dependencies, while Abstract Factory provides a way to create compatible families of related objects. ASP.NET Core dependency injection (DI) connects interfaces to implementations at runtime; it does not mean every service needs a factory.

In practice, keep application rules and their abstractions in the core, put database and other infrastructure implementations in an outer project, and register those implementations in the ASP.NET Core host. Add Abstract Factory when a client must create several related product types in coordinated variants—not merely to wrap a single injected service.

What each pattern does

Onion Architecture sets dependency direction

In Onion Architecture, source-code dependencies point inward. The Application Core contains business rules and defines abstractions for capabilities it needs, such as data access or network calls. Infrastructure implements those abstractions and depends on the core; the core does not depend on infrastructure details. Microsoft groups this approach with Hexagonal Architecture, Ports-and-Adapters, and Clean Architecture, and uses the name Clean Architecture in its e-book. Microsoft’s architecture overview describes the boundaries and their use in ASP.NET Core applications.

This is a rule about compile-time dependencies, not a requirement to deploy each project separately. In a monolithic application, the UI, core, and infrastructure can run together as one application.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Abstract Factory creates compatible product families

Abstract Factory is a creational pattern for producing families of related objects without specifying their concrete classes. A factory interface typically has a creation method for each product type; concrete factories create a matching variant. For example, a platform-specific UI factory could create both a button and a checkbox designed for the same operating system. The client uses the factory and product interfaces rather than concrete classes. Refactoring.Guru’s Abstract Factory reference explains the pattern’s structure and trade-offs.

The distinction is practical: Onion Architecture answers which layer may depend on which; Abstract Factory answers how a client requests a related set of objects. They can be combined, but neither requires the other.

Where the pieces belong in an ASP.NET Core application

A common project layout assigns responsibilities like this. It is a practical mapping of the architectural guidance, not a mandatory Microsoft project template.

Part Typical contents Dependency role
Application Core Business model, entities, aggregates, interfaces, domain services, specifications, domain events and handlers, custom exceptions, guard clauses, and dependency-free DTOs. Defines the abstractions application rules need; should not reference infrastructure implementations.
Infrastructure EF Core DbContext and migrations, repositories, file logging, SMTP notification, and other infrastructure-specific services. References the core to implement its interfaces.
UI or host Controllers, filters, middleware, views, view models, and host configuration. Uses core abstractions and serves as the composition root where implementations are wired.

If the application genuinely needs an Abstract Factory, place the factory and product interfaces in the core when they express a capability required by application rules. Put a concrete factory and its infrastructure-dependent products in an outer project. The host then registers that factory with DI. This preserves the inward dependency rule while allowing the client to work with abstractions.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

A host project may need a reference to Infrastructure so its startup code can register concrete types. Keep direct references to infrastructure types confined to that composition root rather than letting business logic depend on them. For current ASP.NET Core hosting, this setup is typically in Program.cs; older applications may use Startup.

How dependency injection fits in

ASP.NET Core’s built-in DI container constructs services and supplies their dependencies, commonly through constructor injection. At startup, the host registers an implementation for an interface; application code requests the interface. This wiring supports the architecture’s runtime connections without changing the compile-time dependency direction. See Microsoft’s ASP.NET Core dependency injection guidance for .NET 10, last updated September 22, 2026.

For example, if a use case needs one repository implementation, define the repository interface in the core, implement it in Infrastructure, and register the implementation in the host. The use case receives the interface through its constructor. It does not need an Abstract Factory simply because DI is involved.

Microsoft cautions against injecting a factory that merely resolves dependencies dynamically, since that can become a service-locator variation. Prefer explicit constructor dependencies. A factory is useful when object creation itself is a meaningful capability the client needs, such as choosing or creating a coordinated family of products.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Best Value
Sale
Programming ASP.NET Core (Developer Reference)
  • Applying all key ASP.NET Core components, including MVC for HTML generation, .NET Core, EF Core, ASP.NET Identity, dependency injection, and more
  • Integrating ASP.NET Core with leading client-side frameworks, including Bootstrap
  • ASP.NET Core code for implementing business logic and data transformations
  • Handling configuration, routing, controllers, views, and common tasks (including posting forms and presenting data)
  • Performing complementary tasks: error handling, logging, application design, authentication, localization, and more
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

When Abstract Factory is worth adding

Use the pattern when several related product types must vary together and clients should remain independent of their concrete classes. A concrete factory can be selected during application initialization—for example, from configuration or environment—and create products that belong to the same variant.

  • There are multiple related product types. The client needs more than one object, and their relationship matters.
  • Variants must stay compatible. A chosen configuration or environment determines which matching products are created.
  • Clients should not know concrete classes. Code should request products through abstractions, not branch on implementation types.
  • The boundary is worth the added design. The extra factory and product interfaces prevent meaningful coupling or incompatible combinations.

If the client only consumes one service and there is no coordinated family of objects, constructor injection is usually simpler. Abstract Factory adds interfaces and classes; that complexity is justified when it solves a real creation and compatibility problem, not just because the application has multiple projects.

A practical decision

Question If yes If no
Must the client create multiple related object types? Consider a factory interface with a creation method for each product. Use direct constructor injection for the needed service.
Must those objects be selected as a compatible variant? Use concrete factories to create each coordinated family. A general factory may add indirection without a clear benefit.
Does application logic depend only on core abstractions? The dependency direction is consistent with Onion Architecture. Move the abstraction inward or move infrastructure-specific use outward.
Can the host wire implementations at startup? Register the chosen implementation in the composition root. Revisit project boundaries and how the host accesses registration code.

For a single repository implementation, an interface in the core plus its Infrastructure implementation and a host registration is generally sufficient. For a platform-dependent UI that must create a matching button and checkbox, Abstract Factory can keep selection and compatibility out of the client. In both cases, DI handles wiring; the pattern choice depends on the client’s object-creation needs.

Testing and project boundaries

Keeping application rules isolated behind core abstractions makes it easier to test those rules without real infrastructure. Infrastructure implementations can be tested separately with the external dependencies they require. The architecture is most useful for non-trivial monolithic ASP.NET Core applications; introducing layers and projects for their own sake can add ceremony without improving a small application.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Quick Recap

Bestseller No. 2
SaleBestseller No. 5
Programming ASP.NET Core (Developer Reference)
Programming ASP.NET Core (Developer Reference)
Integrating ASP.NET Core with leading client-side frameworks, including Bootstrap; ASP.NET Core code for implementing business logic and data transformations
$24.99

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.