0

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.

  1. 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.
  2. 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)
RB.
  • 36,301
  • 12
  • 91
  • 131
w0051977
  • 15,099
  • 32
  • 152
  • 329
  • Can you describe more specifically the scenario of the solution you are modeling? – Riccardo Nov 12 '12 at 11:14
  • @Riccardo, thanks. The dataaccesslayer and the businesslogic layer could throw exceptions and I want to log these. I could add a logging facility in the user interface tier (for both dataaccesslayer and businesslogiclayer) or create a Utilities project for this purpose. – w0051977 Nov 12 '12 at 11:17

4 Answers4

2

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.

jgauffin
  • 99,844
  • 45
  • 235
  • 372
  • Can you explain what relevance DI has with this question? I understand that DI is the process of passing instance variables to the constructor, but I don't understand the relevance to the question (I am missing something). Once I understand this I will mark the answer. Thanks. – w0051977 Nov 12 '12 at 19:57
  • @w0051977: DI also usually means coding against abstractions. Hence you have to know a lot less about the application each time you do something. It also makes it easier to refactor the application as it grows (just reconfigure the container instead of every place where the refactored code is used) – jgauffin Nov 12 '12 at 20:01
  • Could you provide an example? Thanks – w0051977 Nov 12 '12 at 20:31
  • Thanks. I have read the article. Are you saying have a different project for DI? I still don't understand the relevance to the question (I am missing something). Thanks. – w0051977 Nov 13 '12 at 07:28
  • Are you able to answer the question in my last comment? I will then mark your answer as the accepted answer. – w0051977 Nov 13 '12 at 18:34
  • No. DI is a pattern. Use it in all your projects, but keep the container in the root project. – jgauffin Nov 13 '12 at 18:40
  • I see. Would you have a project called Utilities for classes that are common to multiple projects or just use DI? (this really is the last question). – w0051977 Nov 13 '12 at 18:44
  • I would probably have something like `Utilities` – jgauffin Nov 13 '12 at 18:46
  • Thanks - I have marked this answer. Would you ever have more than one DLL in the BLL? – w0051977 Nov 13 '12 at 19:09
  • Dynamic Link Library in the Business Logic Layer. Sorry for the confusion. – w0051977 Nov 13 '12 at 19:43
0
  1. 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.

  2. You should have each setting in one place only, so the UI layer seems to be a good place.

Guffa
  • 687,336
  • 108
  • 737
  • 1,005
  • There would be a circular dependancy if I chose your option 1 i.e. the DAL would access the BLL and vice versa. Am I misunderstanding something? – w0051977 Nov 12 '12 at 11:21
  • @w0051977: Yes, then you are misunderstanding someting. The methods in the business layer would only be for the UI layer to access the methods, the data layer would access them directly. – Guffa Nov 12 '12 at 13:23
  • The business layer could call the data layer. In your answer the data layer would also access the business layer. Wouldn't this introduce a circular dependancy? – w0051977 Nov 12 '12 at 15:47
  • @w0051977: No, the data layer would not call the business layer. – Guffa Nov 12 '12 at 16:25
0
  1. Yes, create another project for logging. I would recommend using Log4Net within that new project.

  2. 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.

Joe Ratzer
  • 18,176
  • 3
  • 37
  • 51
  • Thanks. Do you mean have a project for DI? – w0051977 Nov 12 '12 at 11:20
  • No, use DI to inject your data access layer into your business logic layer. DI really divorces the dependencies between the layers. – Joe Ratzer Nov 12 '12 at 11:22
  • 1
    Should that be "No, don't create another project for logging, since "logging" is a solved problem use Log4Net"? – Binary Worrier Nov 12 '12 at 11:32
  • No, I'd prefer to create another project for logging. Add a Log4Net refernce to that project and implement a generic logging interface using Log4Net. Therefore, whenever a change of logging framework is required no other code is changed - just implment the logging interface with the new framework. – Joe Ratzer Nov 12 '12 at 11:35
  • @JoeR: I've never ever switched logging framework in an application. Anyone doing so have probably not done their homework before choosing the logger. so imho being able to switch logging implementation is a non-issue. – jgauffin Nov 12 '12 at 12:15
  • I'd agree it is highly unlikely, but doing so takes almost no time and doesn't tie you down. I don't see it as a lack of homework, and more down to thinking that one day there'll be a new logging framework that is even better than Log4Net. It's been a long wait so far! :-) – Joe Ratzer Nov 12 '12 at 12:28
  • We don't want to be tied down by our current data access framework, so why do that with your choice of logging? – Joe Ratzer Nov 12 '12 at 12:30
  • Also, there are some very silly companies out there that suddenly say "there should be no use of open-source code". If that happens you can easily change Log4Net for a non-open-source alternative. Of course, you should probably start looking for a job at a better company too. :-) – Joe Ratzer Nov 12 '12 at 12:47
  • I don't log a single line in my data access layer. I use exceptions & argument validation instead. – jgauffin Nov 12 '12 at 13:35
  • I don't understand what you mean, I don't log a single line in my data access code either. – Joe Ratzer Nov 12 '12 at 13:46
  • I misread. I though you said that your DL shouldn't be tied to a specific logging implementation. So here's the real comment to your comment: You can't compare DL abstractions with logging abstractions since the data abstraction is not really to abstract away an OR/M but to be able to do more things in the DL such as caching or fetch a specific query using ADO.NET (since the OR/M didn't work in that case) – jgauffin Nov 12 '12 at 15:09
  • I think there is an aspect of abstracting away an OR/M - using DI allows projects to switch OR/Ms. Also, you can write specific queries, even stored procedures, and call those within all decent OR/Ms - you wouldn't need to use, for example, ADO.NET in those circumstances. But I think we're generally agreeing really. – Joe Ratzer Nov 12 '12 at 15:33
0
  1. 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.
  2. 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.
Riccardo
  • 1,490
  • 2
  • 12
  • 22