I am trying to create a structure for a large .NET application I am developing. I am planning to create three projects:
DataAccessLayer
BusinessLogicLayer
UserInterfaceLayer
I have two questions.
What would you do with functionality that is common to all three layers e.g. logging errors to a text file. Circular dependencies are not allowed in .NET. I believe the best approach is to create a forth project called Utilities.
Would you have .config files in all of the projects or just the user interface layer (passing all the config parameters as arguements to constructors in the BLL and DLL)
What would you do with functionality that is common to all three layers e.g. logging errors to a text file. Circular dependencies are not allowed in .NET. I believe the best approach is to create a forth project called Utilities.
Cross cutting concerns usually ends up in a forth assembly. But in the logger case just use one of the existing frameworks that devs are used to. for instance nlog or log4net.
Circular dependencies is a smell (high coupling or low cohesion) and should not be allowed anywhere.
Someone else suggested Dependency Injection and it's a great way to reduce coupling and therefore increase maintainability. I've written an article here: http://www.codeproject.com/Articles/386164/Get-injected-into-the-world-of-inverted-dependenci
Would you have .config files in all of the projects or just the user interface layer (passing all the config parameters as arguements to constructors in the BLL and DLL)
I would rather create an configuration abstraction. Something like IConfigurationRepository. Then it doesnt matter if the configuration is stored in web.config or somewhere else.
Having a fourth project is one solution, another is to place that in the data layer, and have methods in the business layer that lets the UI layer access them.
You should have each setting in one place only, so the UI layer seems to be a good place.
You could create a single logging project and add it to all the other projects but in my opinion you should add a logger configuration file for each one becouse modeling a three tier architectures as you are doing means first modeling three layers logically separated so you should be able to develop and test each of them separately.
if you have specific layer configuration settings(e.g. one or more layer stay on different servers for strong performance contraints required) use a different configuration file for each layer. If you have the same configuration settings you could use an only one configuration file in the user interface but be aware that if you change the user interface you will have to replace all your settings and this in my opinion might be a serious problem.
Yes, create another project for logging. I would recommend using Log4Net within that new project.
I would keep config settings at the top level - the UI layer - and pass anything necesssary down to the other layers.
You don't mention DI, I would definitely use DI - that should be a priority.
Related
Currently in our project we have layered architecture implemented in following way where Controller, Service, Repository are placed in the same package for each feature, for instance:
feature1:
Feature1Controller
Feature1Service
Feature1Repository
feature2:
Feature2Controller
Feature2Service
Feature2Repository
I've found following example of arch unit test where such classes are placed in dedicated packages https://github.com/TNG/ArchUnit-Examples/blob/master/example-junit5/src/test/java/com/tngtech/archunit/exampletest/junit5/LayeredArchitectureTest.java
Please suggest whether there is possibility to test layered architecture when all layers are in single package
If the file name conventions are followed properly across your project, how about you write custom test cases instead of using layeredArchitecture().
For Example:
classes().that().haveSimpleNameEndingWith("Service")
.should().onlyBeAccessed().byClassesThat().haveSimpleNameEndingWith("Controller")
noClasses().that().haveSimpleNameEndingWith("Service")
.should().accessClassesThat().haveSimpleNameEndingWith("Controller")
I know this question is rather old. But for the record, this has been possible for a while using predicates for the layers, e.g.
layeredArchitecture().consideringAllDependencies()
.layer("Controllers").definedBy(HasName.Predicates.nameEndingWith("Controller"))
.layer("Services").definedBy(HasName.Predicates.nameEndingWith("Service"))
.layer("Repository").definedBy(HasName.Predicates.nameEndingWith("Repository"))
.whereLayer("Controllers").mayNotBeAccessedByAnyLayer()
.whereLayer("Services").mayOnlyBeAccessedByLayers("Controllers")
.whereLayer("Repository").mayOnlyBeAccessedByLayers("Services")
However, I'm not sure how well this works in practice. Because usually you don't just have classes following this naming pattern and that's it. A service might also have some POJO as method parameter type (e.g. MyInput) and that should maybe for example not be used by repositories as well. Also, using forward dependency rules (mayOnlyAccessLayers(..)) this might then cause unwanted violations.
I am trying to understand Microsoft.practices.Unity.
So, I have this solution:
webproject
business classlibrary project as my logic tier
data classlibrary project as my data access tier
And I want to use Unity to separate web tier from logic and separate logic tier from data, using DI.
I have created an unity.config file in my web project, cause I wanna control the registration from a configuration file, and not inside binary code. This is OK for me. I am using Unity.MVC4.
But, with that, I only resolve my dependency injection only from web to business tier. And how can I make the same thing for business to data tier ?
I have already seen some web examples but I am still confused, because no example shows me the process through the web tier to data tier, step by step, to understand how to implement the Unity DI.
I would like to see a simple example, with a n-tier solution with total DI implementation with Unity.
Prevent from using the config file for registration of dependencies. This is brittle and error prone and you can only do a subset of things that you can do in code. If you're doing this because you want to prevent dependency references, please note that by using the config file, the same referencing still applies, but now it's implicit and there's no compile time checking to help you.
This doesn't mean though that you should never use the config file, but you should only use it to configure things that can actually change during or after deployment. Most things shouldn't change during that time, since most changes must be changed by a developer, either manually by starting the application, or in an automated fashion using unit tests.
Neither would place class names in the config file for the same reason as it is brittle. Using configuration switches is usually much better, since this allows you to move the class names to the code (with a switch case statement or if statement to change configuration based on the config setting) and enables compile time checking.
For the rest of your questions, Tuzo's link will probably give you enough information.
I'm currently breaking down an application into several frameworks, three in total. I believe frameworks are the best solution for this as I can have several units of code independent of each other along with all accompanying code, such as unit tests, without "polluting" the main project.
Now, my problem is, I want to make these frameworks as independent as possible, but they all require certain constants to be made available to them - the same constants on all frameworks. Those constants will also need to be available on the main application. So, what is the best place to define those constants?
I could define them on a single framework, declare that the main framework and make all others depend on it. Or I could define them on a header file and make all constants and the main application depend on it.
What is your suggestion?
This question comes up in any package or library system, all the way back to Fortran in the '60s.
The best solution is to have a base package/library that everything else depends on. Then make each separate framework only depend on that base, not on each other. Then make the application depend on all of the libraries, so you get a "diamond" dependency graph:
// application
// data rules presentation
// base
Like a lot of things, I'm sure there's a good reason for this, so please help me understand...
Why, by default, do WCF services store settings in app.config?
This has been so frustrating trying to work with multiple Silverlight class libraries. These class libraries are supposed to be completely independent from each other, and this dependency on the app.config seems to cause the following headaches:
Single Responsibility Principle - I should be able to add a reference to a class library and go. If that class library uses a service reference, this idea is shot before I even start coding against it.
Muddy Configuration - To get other libraries to work, I have to copy and paste the service configurations into the "main" application configs. If an endpoint changes in any way, I can't just worry about a new version of that class DLL - I have to worry about anything that uses it, too.
Complex Alternatives - Programmatically creating the endpoint isn't pretty. Period.
There has to be a better way. Why doesn't WCF at least separate the service configurations into a ServiceName.config or something that gets copied to an output directory. What am I missing? How do you deal with this?
Because the alternatives aren't pretty either. The problem with "ServiceName.config" is that ServiceName also needs to be configurable.
The root problem is having Service references in libraries to start with. And a library component cannot dictate a binding for an App. So your SRP argument does not hold.
I concur with #Henk - library assemblies shouldn't have WCF references. If for some reason it does require one, i would use dependency injection, and pass the service reference in to the library function - this is vitally important for maximum testing benefit.
I also don't buy your argument of "Programmatically creating the endpoint isn't pretty". Creating and assigning an end point is just a couple of lines of code, and is a technique i use almost exclusively with my Silverlight components (e.g. if no address is specified within the ServiceReferences.ClientConfig file then i fall back to known service locations within the hosting application, in which case those endpoints are programmatically created).
Basically, if you don't mind the couple of lines of code required to programmatically create an end point, then you can store your address details anywhere, in any config file. You only need to store the addresses in the app.config if you are going for a purely declarative approach.
NInject's module architecture seems useful but I'm worried that it is going to get in a bit of a mess.
How do you organise your modules? Which assembly do you keep them in and how do you decide what wirings go in which module?
Each subsystem gets a module. Of course the definition of what warrants categorisation as a 'subsystem' depends...
In some cases, responsibility for some bindings gets pushed up to a higher level as a lower-level subsystem/component is not in a position to make a final authoritative decision - in some cases this can be achieved by passing parameters into the Module.
Replying to my own post after a couple of years of using NInject.
Here is how I organise my NInjectModules, using a Book Store as an example:
BookStoreSolution
Domain.csproj
Services.csproj
CustomerServicesInjectionModule.cs
PaymentProcessingInjectionModule.cs
DataAccess.csproj
CustomerDatabaseInjectionModule.cs
BookDatabaseInjectionModule.cs
CustomSecurityFramework.csproj
CustomSecurityFrameworkInjectionModule.cs
PublicWebsite.csproj
PublicWebsiteInjectionModule.cs
Intranet.csproj
IntranetInjectionModule.cs
What this is saying is that each project in the system comes prepackaged with one or more NInject modules that know how to setup the bindings for that project's classes.
Most of the time an individual application is not going to want to make significant changes to the default injection modules provided by a project. For example, if I am creating a little WinForm app which needs to import the DataAccess project, normally I am also going to want to have all the project's Repository<> classes bound to their associated IRepository<> interfaces.
At the same time, there is nothing forcing an individual application to use a particular injection module. An application can create its own injection module and ignore the default modules provided by a project that it is importing. In this way the system still remains flexible and decoupled.