DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • Building a Microservices API Gateway With YARP in ASP.NET Core Web API
  • How to Enhance the Performance of .NET Core Applications for Large Responses
  • Developing Minimal APIs Quickly With Open Source ASP.NET Core
  • Architecting Scalable ASP.NET Core Web APIs With Abstract Factory Method and Onion Architecture

Trending

  • Why SAP S/4HANA Landscape Design Impacts Cloud TCO More Than Compute Costs
  • Chat with Your Oracle Database: SQLcl MCP + GitHub Copilot
  • 11 Agentic Testing Tools to Know in 2026
  • Architecting Sub-Microsecond HFT Systems With C++ and Zero-Copy IPC
  1. DZone
  2. Software Design and Architecture
  3. Integration
  4. Revolutionizing Content Management

Revolutionizing Content Management

Implementing the Composite Pattern along with Clean Architecture in ASP.NET Core Web API involves multiple layers: presentation, application, domain, and infrastructure.

By 
Sardar Mudassar Ali Khan user avatar
Sardar Mudassar Ali Khan
·
Oct. 27, 23 · Tutorial
Likes (2)
Comment
Save
Tweet
Share
4.4K Views

Join the DZone community and get the full member experience.

Join For Free

Implementing the Composite Pattern along with a Clean Architecture in an ASP.NET Core Web API involves multiple layers such as Presentation, Application, Domain, and Infrastructure. Additionally, you would need to create models, repositories, and services to achieve complete CRUD functionality. Below is a simplified example demonstrating the implementation. Note that this is a basic example, and in a real-world scenario, you might need to consider more advanced features, error handling, and security measures.

Let's consider a scenario where we have a DZoneArticle entity, and we want to perform CRUD operations on it.

1. Domain Layer

C#
 
// Sardar Mudassar Ali Khan
// Domain Layer
namespace APIDevelopmentWithCleanArchitectureAndCompositePattern.Domain.Entities
{
    public interface IDZoneArticleComponent
    {
        int Id { get; }
        string Title { get; set; }
        string Content { get; set; }

        void Display();
    }

    public class DZoneArticle : IDZoneArticleComponent
    {
        public int Id { get; set; }
        public string Title { get; set; }
        public string Content { get; set; }

        public void Display()
        {
            Console.WriteLine($"Article: {Title}, Content: {Content}");
        }
    }

    public class DZoneArticleComposite : IDZoneArticleComponent
    {
        public int Id { get; set; }
        public string Title { get; set; }
        public string Content { get; set; }

        private List<IDZoneArticleComponent> _children = new List<IDZoneArticleComponent>();

        public void Add(IDZoneArticleComponent component)
        {
            _children.Add(component);
        }

        public void Remove(IDZoneArticleComponent component)
        {
            _children.Remove(component);
        }

        public void Display()
        {
            Console.WriteLine($"Composite Article: {Title}, Content: {Content}");

            foreach (var child in _children)
            {
                child.Display();
            }
        }
    }
}


In this example, DZoneArticleComposite is a composite class that can hold a list of IDZoneArticleComponent, which can be either individual articles (DZoneArticle) or other composite articles. The Display method allows you to traverse the composite structure and display the articles.

2. Application Layer

C#
 
// Application Layer
namespace APIDevelopmentWithCleanArchitectureAndCompositePattern.Application.Interfaces
{
    public interface IDZoneArticleService
    {
        Task<IDZoneArticleComponent> GetCompositeAsync(int id);
        Task<int> CreateAsync(IDZoneArticleComponent articleComponent);
        Task UpdateAsync(IDZoneArticleComponent articleComponent);
        Task DeleteAsync(int id);
    }
}
C#
 
// Sardar Mudassar Ali khan
// Application Layer
namespace APIDevelopmentWithCleanArchitectureAndCompositePattern.Application.Services
{
    public class DZoneArticleService : IDZoneArticleService
    {
        private readonly IDZoneArticleRepository _repository;

        public DZoneArticleService(IDZoneArticleRepository repository)
        {
            _repository = repository;
        }

        public async Task<IDZoneArticleComponent> GetCompositeAsync(int id)
        {
            return await _repository.GetCompositeAsync(id);
        }

        public async Task<int> CreateAsync(IDZoneArticleComponent articleComponent)
        {
            return await _repository.CreateAsync(articleComponent);
        }

        public async Task UpdateAsync(IDZoneArticleComponent articleComponent)
        {
            await _repository.UpdateAsync(articleComponent);
        }

        public async Task DeleteAsync(int id)
        {
            await _repository.DeleteAsync(id);
        }
    }
}


3. Infrastructure Layer

C#
 
// Sardar Mudassar Ali khan
// Infrastructure Layer
namespace APIDevelopmentWithCleanArchitectureAndCompositePattern.Infrastructure.Repositories
{
    public class DZoneArticleRepository : IDZoneArticleRepository
    {
        private readonly YourDbContext _dbContext;

        public DZoneArticleRepository(YourDbContext dbContext)
        {
            _dbContext = dbContext;
        }

        public async Task<IDZoneArticleComponent> GetCompositeAsync(int id)
        {
            // Implement logic to get a composite article by id
            return await _dbContext.DZoneArticleComposites
                .Include(a => a.Children) // Assuming Children is a navigation property in your composite entity
                .FirstOrDefaultAsync(a => a.Id == id);
        }

        public async Task<int> CreateAsync(IDZoneArticleComponent articleComponent)
        {
            // Implement logic to create a composite article
            _dbContext.Add(articleComponent);
            await _dbContext.SaveChangesAsync();
            return articleComponent.Id;
        }

        public async Task UpdateAsync(IDZoneArticleComponent articleComponent)
        {
            // Implement logic to update a composite article
            _dbContext.Entry(articleComponent).State = EntityState.Modified;
            await _dbContext.SaveChangesAsync();
        }

        public async Task DeleteAsync(int id)
        {
            // Implement logic to delete a composite article
            var article = await _dbContext.DZoneArticleComposites.FindAsync(id);
            if (article != null)
            {
                _dbContext.DZoneArticleComposites.Remove(article);
                await _dbContext.SaveChangesAsync();
            }
        }
    }
}


Explanation:

  1. GetCompositeAsync(int id):
    • This method uses Entity Framework's Include method to eagerly load the children of the composite article. Adjust the navigation property (a.Children) based on your actual data model.
  2. CreateAsync(IDZoneArticleComponent articleComponent):

    • This method adds the new composite article to the context and saves changes to the database.
  3. UpdateAsync(IDZoneArticleComponent articleComponent):

    • This method updates the state of the composite article in the context and saves changes to the database.
  4. DeleteAsync(int id):

    • This method finds the composite article by its id, removes it from the context, and saves changes to the database.

Make sure to adapt these implementations based on your actual data model, relationships, and business logic. The provided examples assume certain conventions, so adjust them according to your specific application requirements.

4. Presentation Layer (Web API Controllers)

C#
 
// Sardar Mudassar Ali Khan
// Presentation Layer
namespace APIDevelopmentWithCleanArchitectureAndCompositePattern.WebApi.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class DZoneArticleController : ControllerBase
    {
        private readonly IDZoneArticleService _articleService;

        public DZoneArticleController(IDZoneArticleService articleService)
        {
            _articleService = articleService;
        }

        [HttpGet("{id}")]
        public async Task<IActionResult> GetComposite(int id)
        {
            var compositeArticle = await _articleService.GetCompositeAsync(id);
            if (compositeArticle == null)
                return NotFound();

            return Ok(compositeArticle);
        }

        [HttpPost]
        public async Task<IActionResult> Create([FromBody] IDZoneArticleComponent articleComponent)
        {
            var id = await _articleService.CreateAsync(articleComponent);
            return CreatedAtAction(nameof(GetComposite), new { id }, articleComponent);
        }

        [HttpPut]
        public async Task<IActionResult> Update([FromBody] IDZoneArticleComponent articleComponent)
        {
            await _articleService.UpdateAsync(articleComponent);
            return NoContent();
        }

        [HttpDelete("{id}")]
        public async Task<IActionResult> Delete(int id)
        {
            await _articleService.DeleteAsync(id);
            return NoContent();
        }
    }
}


Conclusion

In conclusion, the provided code snippets demonstrate the implementation of a composite pattern in a Clean Architecture with ASP.NET Core Web API. The example revolves around managing articles, where a composite article can contain other articles or composite articles.

Key Components

  1. Domain Layer:

    • Defines the DZoneArticle entity representing an individual article.
    • Introduces the IDZoneArticleComponent interface and its implementations (DZoneArticle and DZoneArticleComposite) for the Composite Pattern.
  2. Application Layer:

    • Defines the IDZoneArticleService interface with methods for CRUD operations on composite articles.
    • Implements the DZoneArticleService class, which interacts with the repository and performs operations on composite articles.
  3. Infrastructure Layer:

    • Defines the IDZoneArticleRepository interface with methods for interacting with the database.
    • Implements the DZoneArticleRepository class, providing the logic to fetch, create, update, and delete composite articles using Entity Framework.
  4. Web API Controllers:

    • Defines a Web API controller (DZoneArticleController) that exposes endpoints for CRUD operations on composite articles.

Conclusion

The provided code emphasizes the use of the Composite Pattern to manage composite articles in a hierarchical structure. The Clean Architecture principles separate concerns into layers, promoting maintainability and testability. The Web API controllers act as an entry point for external requests, invoking the application layer services, which in turn interact with the repository to perform operations on the database.

Please adapt the code to your specific needs, considering additional features, error handling, security, and validation based on your application requirements. The examples serve as a starting point, and the implementation can be extended and refined based on your project's unique characteristics.

API ASP.NET ASP.NET Core Composite pattern Web API

Opinions expressed by DZone contributors are their own.

Related

  • Building a Microservices API Gateway With YARP in ASP.NET Core Web API
  • How to Enhance the Performance of .NET Core Applications for Large Responses
  • Developing Minimal APIs Quickly With Open Source ASP.NET Core
  • Architecting Scalable ASP.NET Core Web APIs With Abstract Factory Method and Onion Architecture

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook