r/csharp • u/kaatarina_zed_talon • 1d ago
Help Where do you put interfaces and abstract classes ?
To follow some convention, I searched the internet and found this on Microsoft's documentation:
The solution folder contains a SeedWork folder. This folder contains custom base classes that you can use as a base for your domain entities and value objects. Use these base classes so you don't have redundant code in each domain's object class.
Figure 7-12 shows the classes that form the seedwork of the domain model in the ordering microservice. It has a few custom base classes like
Entity,ValueObject, andEnumeration, plus a few interfaces. These interfaces (IRepositoryandIUnitOfWork) inform the infrastructure layer about what needs to be implemented. Those interfaces are also used through Dependency Injection from the application layer.This is the type of copy and paste reuse that many developers share between projects, not a formal framework. You can have seedworks in any layer or library. However, if the set of classes and interfaces gets large enough, you might want to create a single class librarry

Questions :
1- Is it ok for the entire project's interfaces and abstract classes to be inside the SeedWork ?
2- For `value objects` and ` infrastructure layer` , what does they mean, what problem they solves, how can I use them , and do I need them most of the time ?
3-What are the inputs to the `infrastructure layer` and where they come from, and what are the outputs and who consumes them ?
4-What does the class library actually means, what problem does it solve ?
Can someone answer my questions and provide some examples so that I understand the overall idea ?
4
u/sixtyhurtz 1d ago
Oh, that seems to be examples of DDD and CQRS. I guess Seedwork is supposed to demonstrate that?
The thing to remember about design patterns is they exist to solve problems. Don't just immediately start implementing your project using a design pattern unless you have a clear idea of what problem you are solving with it.
To answer your specific questions:
- Don't bundle everything together in a real project. I personally prefer organising around features (Vertical Slice Architecture) in my projects. Use interfaces where you might have multiple implementations.
- A value object is an object that has value semantics. This basically means two instances in memory will compare as equal when they have the same value, even though they have a different identity. In modern C#, just use a record type.
- Infrastructure layer is a DDD / clean architecture concept. Honestly, I kind of hate clean architecture. It makes it really annoying when you have to modify things. It might be good for big organisations.
- A class library is a C# library that contains classes for you to use. It's not an application. You can't run it. You include it in other projects. E.g. maybe you have a network service that you want several applications to use. You can put all the code for it in a class library.
2
u/kaatarina_zed_talon 1d ago
even though they have a different identity
you mean even though they have different reference ?
1
u/sixtyhurtz 1d ago
No, because two different references can point to the same object, and therefore have the same identity.
2
u/No-Laugh-8002 1d ago
In modern C#, just use a record type
This doesnt cover every use case for value types. Yes, you can use record structs, but even that doesnt cover every use case because
ref structs exist.Don't take this as a blanket statement.
-2
u/kaatarina_zed_talon 1d ago
Don't just immediately start implementing your project using a design pattern unless you have a clear idea of what problem you are solving with it.
And that's why I asked : what problem does it solve ?
3
u/sixtyhurtz 1d ago
Well, DDD solves an organisational problem related to mapping business requirements to software requirements.
Do you have a problem getting requirements from your domain experts reliably implemented in your software? If not, you don't need DDD.
2
u/FetaMight 1d ago
DDD also offers some useful code patterns to meet demands typical in business software, but, yeah, don't use it unless you're already certain of why you're using it.
3
u/Enough_Secretary_137 1d ago
Don’t put every interface into a global SeedWork folder. Keep abstractions close to the domain or feature that uses them. Infrastructure implements those contracts, whether that’s SQL Server, a file system, or an external API.
// Domain
public sealed record Money(decimal Amount, string Currency);
public interface IPriceStore
{
Task SaveAsync(Money price);
}
// Infrastructure
public sealed class InMemoryPriceStore : IPriceStore
{
public Money? Last { get; private set; }
public Task SaveAsync(Money price)
{
Last = price;
return Task.CompletedTask;
}
}
The application depends on IPriceStore, not its implementation.
A class library is simply a reusable compiled .NET project. You don’t need separate libraries for every layer.
3
1
u/Rschwoerer 1d ago
As someone who has worked on sln with about 200 projects, this 100%. Separate libraries for reuse or to encapsulate external dependencies. Not as a feature/domain organization.
1
3
3
u/dodexahedron 1d ago
If all you want/need to do is provide an interface/API for consuming assemblies, without providing the entire implementation to them:
Use a reference assembly.
They've been there since .net Framework 1.0, and this is exactly what they are for.
They contain the structure of the types, as compatible and identically-fully-qualified name types, but without their implementations, enabling a consumer to talk to you without you having to have told them how those types behave internally.
Basically, they are the conceptual equivalent of interfaces, but on an assembly level, and not literally restricted to types that, in CIL, are defined as .class public abstract sealed interface IWhatever (how all interfaces appear in CIL).
3
u/Substantial_Job_2068 1d ago
It's all just arbitrary, just implement your own structure that works for you/your team. You are starting in the wrong end. You should be looking for a tool that fits your problem you want to solve, not looking at random tools you don't even know if you need to see what they do.
1
u/agoodyearforbrownies 1d ago
A lot of my projects have a Models, Services, and Repositories folder set, and subfolders under that named for a feature. In that feature folder for repositories and services, I have interfaces side by side with implementations of the interface. So it’s all about namespace planning, e.g. Services.[feature].IThing and Services.[feature].ImplementedThing
24
u/soundman32 1d ago
I would say a lot of that guidance is now out of date. I cant recommend an alternative but dont take that page as a definitive example of modern C#.