I have followed DDD guidelines to structure my project, I have Domain, Infrastructure, Application and Presentation layers.
I have also defined a cross-cutting project called Common. All other projects have dependency on Common.
One of the things that I need in Common project is my config/setting values. I have defined all solution wide settings in a DB table. The Common project reads the settings and any other project can access these settings through Common project...
How should Common project access the DB? Anywhere else in the solution, I use Infrastructure layer to read from DB, but if I reference Infrastructure in Common project, I would get circular dependency.
Should Common project have it's own DB Reader? Or putting all the config in the Common project was not the correct design at the first place?
The common package could be organized by feature. Here the IConfigProvider implementations would live in the same package as the interface.
E.g.
You could also consider global configuration as a supporting BC and implement the appropriate anti-corruption layer in each downstream context, where every context has it's own view and interpretation of such configuration.
Dependencies are always an interesting thing.
Since you haven't specified what languages/environments you are using and I have experience with C# I will use techniques and terminology related to strong typed OO languages like it.
Let's say that we will separate interface and implementation. I will use the c# notation that an interface begins with capital 'I' to make more clear what is an interface.
Your repositories are part of your domain. Lets say you have Account entity and you have AccountRepository for this entity.
What we will do is separate the interface for this repository from it's implementation. We will have IAccountRepository and a concrete implementation (maybe more than one, but this is very rare) for it: AccountRepository.
If we want to use SQL database we may have SQLAccountRepository. If we want to use MongoDB we may have MongoDBRepository. Both of these concrete repositories will implement the interface IAccountRepository.
IAccountRepository is part of your Domain, but the implementations (SQL, MongoDB etc.) are part of your Infrastructure layer as they will access external things (SQL server or MongoDB server in this example).
Your dependencies in this case will be 'Infrastructure -> Domain' not 'Domain -> Infrastructure'. This isolates your domain from the Infrastructure as the Infrastructure has reference to the Domain note vice versa.
By using interfaces your Domain only specifies what it needs not how it needs it.
If you apply the same idea you can define interfaces in your Common project for getting (and setting if necessary) settings (ISettingsProvider, IApplicationSettings etc.) and allow the Infrastructure that references Common to provide implementation for these interfaces (SQLSettingsProvider etc.)
You can use dependency injection, service locator or similar technique to bind implementations to interfaces.
Related
When using MVC5 I add a domain layer and storage layer using dependency injection for all the business data. But I have always left the ApplicationDbContext in the main MVC application layer project.
I've read a great many posts on SO and see many people recommend moving the ApplicationDbContext out of the MVC project. I'd like to understand why ApplicationDbContext should or should not be moved. Are there any reasons to not move this context?
On the one hand, ApplicationDbContext uses a data model which suggests it should be moved to the storage layer but that will require large DTO's. On the other hand, ApplicationDbContext really relates primarily to application access and I have a separate roles/permissions functionality for the business data anyway. Several SO posts also suggested checking roles in the application layer, not the domain layer, but that seems suspect; don't we want to check business roles in the domain layer?
So I'm confused and before I go to the work to move the ApplicationDbContext to a different layer, I'd like to make sure I'm making a sound and informed decision.
It is not a must, but it is advisable if you are doing DDD and your project tends to grow large.
Although DDD is not about implementation details, DDD asks for a clear separation of concerns. Then you should separate domain logic from infrastructure.
You could achieve that separation in many ways. One way would be to have a single project with folders for Domain, Application and Infrastructure, and have your DbContext reside in the Infrastructure folder. This is suitable for small projects.
In large projects, however, I would recommend you to evaluate the Clean Architecture, which will take this separation to project level.
I'd like to understand why ApplicationDbContext should or should not be moved. Are there any reasons to not move this context?
It can be moved, there's no rule against it. But the tooling will then require you to specify both startup and database projects as parameters, like this:
dotnet ef database update --project <path> --startup-project <path>
But since you're using MVC5, you're probably not using EF Core. In case of EF 6 or lower, you'll be using the Package Manager Console (PMC) to manage migrations and database-updates, which will make your life easier in that regard, since you can mark you MVC project as the Startup Project from the context menu, and select the target project from a dropdown control in the PMC.
Several SO posts also suggested checking roles in the application layer, not the domain layer, but that seems suspect; don't we want to check business roles in the domain layer?
Yes, roles are related to permissions, which are business rules. People probably recommend checking that in the application layer because you need to pull this data from the database, but you could do it like this:
Use the Specification Pattern to represent roles and permissions as an specification in the Domain Layer. But the IRepository interfaces would best be defined in Application Layer, as they represent infrastructure (which will be concretely implemented in the Infrastructure Layer). So you would start the role-checking in the Application Layer by using repositories to retrieve data, but the actual permission validation would be done by an Specification in the Domain Layer.
That would be one way to do it.
After reading OSGi application design - am I abusing the service framework? and What is the best way of grouping OSGi bundles to make a coherent 'application', I'm now stuck with burning question of how to apply the "don't program OSGi" mantra.
Assuming the bounded context is the entire application and not the individual bundles, I should be free to declare some aggregate root entity in an API bundle, and in the DDD style, a repository for working with said entity. Now, the crux of the matter: an explicit repository appears to be antithetical to the OSGi style because a repository is itself a registry (of domain objects), and this design sidesteps the OSGi service registry. But to do away with the repository would require consumers to program OSGi in order to perform lookups of an entity.
It is said that repositories are just a façade--does this imply that I should create a repository implementation which delegates to the service registry? This does not appear to be a coherent approach since consumers would have two entry points into the domain model: the repository, and the service registry itself. To forgo the repository would no longer be DDD because we're back to mixing domain logic with framework code in a spaghetti-like fashion.
So what's the take-away here? Is domain-driven design incompatible with the "OSGi way," or am I missing some critical concept?
The rationale for not depending on OSGi is that as middleware OSGi visibility in your code makes it less cohesive. Domain code and OSGi code should not mix (just like it should not mix with JMS, Java EE, or any other API). Less cohesive code is more complicated and therefore error prone.
However, you always need some bridging code that links the infra-structure to your domain code. Since this bridging code is going to be coupled to some API anyway, leverage it to the hilt, there is absolutely no use in abstracting yourself from the environment for bridge code.
DS (and Blueprint, iPOJO, etc) hide the registry for the business logic, they are just very convenient ways to provide your domain registry. So with OSGi you hardly have to write any code to have a very powerful repository of domain objects without your domain objects themselves being aware of OSGi.
Yes, if you move your code from OSGi to somewhere else you have to rewrite the bridge code and coming from an OSGi world writing the generic functionality provided by OSGi is surprisingly large. However, not using the OSGi constructs because in event that the app is ported you have to provide is functionality is throwing away money.
Conclusion: domain could should not mix with OSGi, bridge code should leverage OSGi to the hilt.
I think you should simply register the repository as an OSGi service. The bundles that need the repository should reference the service and should only know of the repository interface. Of course this means you have to use either a ServiceTracker in an Activator or e.g. a blueprint context. I prefer the blueprint context as this way you do not have a real java level dependency on OSGi.
Of course this creates a dependency to OSGi in some way but this is not avoidable. The basic idea to follow is that you should keep the OSGi specific code out of your business code and have it in separate classes or in blueprint.
See one of my tutorials which shows a simple application with UI, a model and a persistence impl. While the application is too small to really do DDD the aproach should be fairly compatible. One thing you will notice is that the whole application does not import a single OSGi interface. One nice side effect is that you can easily reuse the code outside OSGi but then of course you have to solve the DI differently.
http://www.liquid-reality.de/x/DIBZ
I have an entity factory which requires access to the file system for construction of the object. I have created a IFileSystem interface, which is being injected into the factory.
Is the the correct way to use an infrastructure service? If so is it recommended to do the same for the entity itself, since important methods on the entity will be required to manipulate the file system also.
It is hard to answer this question without knowing what domain you are working on. It does not seem right though because this would be similar to injecting something like IDatabase. File system and database are persistence technologies and domain logic should be as persistent-agnostic as possible. So you might want to reevaluate this design if your Ubiquitous Language does not include the concept of 'file system'. You can simply restate your intent in a more domain centric terms like ICustomerConstructionInfoProvider. And then inject this interface implementation similarly to how you would inject repositories implementation.
I have a system that talks with the database using repositories. What is the correct definition when it is a remote service? Or better,
Repository is for databases as [...] is for external Web-Services.
I found in many places about ServiceAgents but I don't know if this is the correct definition.
In DDD, Repositories represent a virtual collection of entities (aggregate roots in particular). So, if you have 10M persisted customers, you would work with a repository as if it were a collection of all 10M in memory. Repositories generally only deal with the same types of operations you would find on a collection: Add something, Remove something, Find something in the collection.
If the actual persistence of the data occurs via a Web Service, the implementation of the repository might interact with a Web Service proxy rather than with a database. The fact that the persistence involves a web service doesn't drive how it should be expressed by your domain however. That is to say, whether the data is persisted via direct database calls, an ORM, a Web Service, or a courier pigeon is an implementation detail.
Now, if your domain model has dependencies to be facilitated by external services (e.g. credit card validation, address verification, etc.), this should be expressed as a Domain Service in the form of an interface which defines the required operations in terms of the domain model. To be clear, Domain Services are operations which are logically part of your domain, but don't fit cleanly for some reason or another on a given entity or value object. Behavior facilitated by an external service is just one example of when you might use a Domain Service, so don't think of Domain Services as "the repository pattern for Web Services" or some such thing.
Not sure if this is the official term but I'd refer to this as a "Service Proxy".
I'm just begging to wrap my head around most of the DDD principles but my understanding is that Repositories are generally used to abstract databases but they could be used to wrap anything that behaves as persistent and/or queryable store. So in short I guess what I'm suggesting is that if your service behaves enough like a database then I don't see any problem with using a repository to abstract access to the entities that it deals with.
Otherwise, if the web service doesn't directly deal with data or behavior that is in your domain, then perhaps your case may be a candidate for an infrastructure level service in your application layer.
If anybody has any objections then please comment as I would like to know if I myself am misunderstanding the intended use of repositories.
I want to develop an enterprise app that includes a WindowsForms presentation layer, middle-tier components for business logic and data access, and a MsSQL Server database. Middle-tier components should contain some business objects and will be called from presentation layer using .NET Remoting. Whitch is the best way (and why) to reference these business objects from presentation layer?
A) Create class library project, implementing business objects. Reference this project from presentation layer and middle-tier layer.
B) Create interface library project defining business objects. Create class library project implementing interfaces. Reference class library project from middle-tier layer. Reference interface library project from presentation layer.
C) Create separate class library projects for middle-tier and presentation layer. Reference corresponding project from presentation layer.
There's probably no clear cut and definite answer to this, it depends on what you are doing.
A will often be good enough in many cases. For small 'single app' projects there isn't really any reason why you can't just reference the business object library directly from both UI and BL layers. It's certainly the simplest, and sometimes simplicity is best.
B is probably the "best", You'll be abstracting your actual implementations away so future changes are possible without breaking contracts, and unit testing is easier if you have interfaces. The other advantage of this is that you won't find it too difficult to switch from B to C in the future if you find it necessary.
C is probably overkill in most cases. That said, on larger projects you may find it necessary. I've worked on large client-server n-tier applications that have had as many as three independent sets of data objects. One set used in the DA layer to map and store in the database. A second set in the business logic and network layers for processing and passing over the network, and the third set in the client for binding to the UI. It's worth considering using interfaces for C as well because of the abstraction advantages.
All in all, without knowing exactly your application domain or scope - B is a good starting point.
I've seen all three approaches work well.
What can sometimes be good is to start with A, then as the complexity increases move to B, then C.
In simple projects the "business objects" can be included in the same project as the presentation and persistence tiers - although it may seem heresy, defining the objects using different namespaces can provide enough separation between the "layers".
You may want to reconsider use of .NET Remoting - WCF is by far a better technology and much easier to use.