> For the complete documentation index, see [llms.txt](https://godrose.gitbook.io/solid-net-framework/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://godrose.gitbook.io/solid-net-framework/modularity.md).

# Modularity

### Motivation

Modern-day apps are far from monolith state meaning they are composed of several components. \
These components are loosely-coupled and are often discovered during app startup. This approach allows the developers to substitute the modules easily and encapsulate the required functionality. This greatly aids preserving the Open-Close Principle of S.O.L.I.D. software development.

### Plugin Model

There are all kinds of modules which can range from UI to simple configuration. One of the most frequent use cases for the need of introducing a composition module is to register the private dependencies of an assembly which should be otherwise unknown to the main app. This is actually a plugin case where system can consume any number of plugins by some abstraction without knowing the concrete implementation. (see the similarity to the case of dependency injection where the abstraction is used, too). The composition module would need to simply implement the abstraction:

```csharp
using Solid.Practices.IoC;

class TestCompositionModule : ICompositionModule<IDependencyRegistrator>
{
    public void RegisterModule(IDependencyRegistrator dependencyRegistrator)
    {
        dependencyRegistrator.AddSingleton<IService, Service>();
    }
}
```

These modules are then composed together and executed during app startup thus making sure all related functionality is ready.

### Dependencies

Sometimes modules could depend one on another. These dependencies should be handled by the appropriate class (see **Bootstrapping** for explanation). The information about the dependencies should be  exposed via **IHaveDependencies** interface and the module itself should be identified using **IIdentifiable** interface. Alternatively, the **DependenciesAttribute** and **IdAttribute** can also be used. \
\
Let's see an example of usage:<br>

```csharp
using Solid.Core;
using Solid.Practices.IoC;
using Solid.Practices.Modularity;

class TestCompositionModule : ICompositionModule<IDependencyRegistrator>, IIdentifiable
{
    public void RegisterModule(IDependencyRegistrator dependencyRegistrator)
    {
        //register dependencies
    }

    public string Id => "TestModule";
}

class TestCompositionModule2 : ICompositionModule<IDependencyRegistrator>, IHaveDependencies
{
    public void RegisterModule(IDependencyRegistrator dependencyRegistrator)
    {
        //register dependencies
    }
    
    public string[] Dependencies => new [] {"TestModule"};
}
```

These two modules should be topologically sorted using these dependencies' constraints. This can be achieved using the correspondent extension method

```csharp
var modules = new [] {new TestCompositionModule(), new TestCompositionModule2()};
var sortedModules = modules.SortTopologically();
```

That's it! Now the modules will be invoked in the correct order :)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://godrose.gitbook.io/solid-net-framework/modularity.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
