I have a service layer with a logger class
Service layer references DAL for Logger class to get its email credentials to use while sending email for critical log items.
I want to use this logger inside the DAL since there is stuff that needs to be logged there also - but with my current architecture I cannot.
I see this could somewhat be handled via IOC but my concern with that is if that way I will be addressing the root of the problem, or hiding it using another layer of abstraction.
What would be good good ways to handle this problem?
In general, circular dependencies are undesirable - they complicate debugging, maintenance, and impose limits on how your code can be structured and extended. Eliminate circular dependencies when possible.
If the logger needs very little information to function - then I would suggest reliminating the dependency of the DAL from the logger. Putting emails into a configuration file, or using a separate mechanism embedded within the logger to access them. Logging is a fairly low-level utility function in most systems - you should avoid making the logger dependent on your data access model. Particularly since you want to be able to log information even if the database is unavailable. It's somewhat useless to have a logger that can't function when a data tier is unavailable.
NOTE: Is there a reason you can't use an existing logging library like log4net or NLog?
If, for some reason, that's not possible - then an Inversion of Control (Dependency Injection) solution may be appropriate. Just realize you would need to factor out into a some third assembly the interface that the logger exposes - so that you can safely invoke it from the DAL.
Related
I am aware that logging is a cross cutting concern and I normally use AOP for logging any errors or exceptions in general. However I am facing a scenario where we also have to log specific information about various operations performed, like for example when an operation was successful we have to log that also, we also have to log something if the response from a web service is invalid according to our business rules etc etc. This means that in some scenarios, logging an event becomes specifically part of the business flow and in these specific cases it is not a cross cutting concern.
To handle such scenarios I have made a DBLogger class that simply writes some dynamic messages and error codes to the DB.
Currently I am using the DBLogger class via dependency injection from ILogger interface. When I look at my code it seems like a code smell to me to see that I am injecting this class in every class where I need to log business rules violation. I am considering making the DBLogger class static and using it directly instead of injecting it. This will remove the code clutter a little bit and my constructor will be clean but the dependency will be still there.
My question is what is the recommended way and best practice to handle such scenarios, and how can OOP and design patterns come to rescue in this case to stop me from violating the Open Closed Principal?
I like to inject the logger for the sake of unit testing. It makes it easier to mock the logger and avoid defining the dependencies of the real logger in your unit tests.
Besides if your IOC container defines it for you already, it's transparent and effort less to inject it.
'...in some scenarios, logging an event becomes specifically part of the business flow and in these specific cases it is not a cross cutting concern.'
Sounds like it should be unit tested then. Therefore it should be injected.
Consider decoration or, as TGH highlights, a base class to reduce the noise.
I've been reading a lot about dependency injection and the service locator (anti-?) pattern - a lot of it on StackOverflow (thanks guys :). I have a question about how this pattern works when it's within a n-layer architecture.
I've seen a lot of blog posts where they describe injecting a IDataAccess component into the business objects. E.g.
public class Address
{
IDataAccess _dataAccess;
public Address(IDataAccess dataAccess)
{
this._dataAccess = dataAccess;
}
}
However, I was under the impression that in an n-layer architecture, the UI layer should not need to have any knowledge of the data access layer... or even know that there /is/ a data access layer! If DI requires exposing the IDataAccess interface in the constructors of the BusinessObjects, this then exposes to the UI the fact that the Business Layer uses a data access layer under the hood - something the UI doesn't need to know or care about surely?
So, my fundamental question is: Does DI require that I expose all my lower layer interfaces to all upper layers and is this a good or a bad thing?
Thanks
Edit: To clarify (after a few comments), I know my business object should be ignorant of the which specific implementation of which IDataAccess it uses (hence the Dependency being injected in the constructor) but I thought that the layers above the BO should not know that the Business Object even requires a dependency on a DAL.
This is really a fairly complex topic, and there are many ways of doing an n-tier architecture. No one way is "the right way", and how you do it depends on your needs as much as it does your personal preferences.
Dependency Injection is about managing dependencies. If your object should be unaware of any dependency, then you would not write your objet in the way you mentioned. You would instead have some other service or method that would populate the data in an agnostic way. Data doesn't mean "Database" either. So IDataAccess could mean it comes from a database, or it comes from a network socket or it comes from a file on disk. The whole point here is that Address does not choose what dependencies it creates. This is done through configuration at the composition root.
Things need data, otherwise your app is probably useless. Making your Address object load itself, however, may not be the best way to go about things. A better approach may be with a factory class or service method.
I think the answer is rather simple. Your bottom layers (interface, bll, dal, entities) are just a bunch of libraries. It is up to the client to decide which libraries to be used and it will increase client's flexibility. Moreover they are libraries, so any application-related configurations (connection strings, data caching, etc) lies on the client. Those configuration itself, sometimes also need to be injected and included into Composition Root.
However, if you want to has an uniform logic and not client's flexibility, you can choose web/app services as an additional layer.
1st Layer Entities
2nd Layer Interface
3rd Layer BLL & DAL
4th Layer Web/App Services
5th Layer UI
This way, your composition root exists in one layer (4th). And add your UI just need to add service reference to 4th layer (or 1st if needed). However, this implies the same Mark Seeman's article again, layering is worth the mapping. I assume that you can change the app/web service to Composition Root.
Moreover, this (app/web service) design has pros/cons. Pros:
Your app is encapsulated
Your app is being bridged by app/web services. It is guranteed that your UI don't know the DataAccess, thus fulfill your requirements.
Your app is secured
Simply said, having UI need to access app service is a huge gain in security aspect.
Access Portability
Now your app can be accessed everywhere. It can be connected by 3rd party app (other web) without has relying on dlls.
Cons:
Overhead cost during service call
Authentication, network connection, etc, will cause overhead during webservice call. I'm inexperienced for the performance impact but it should be enough for high traffic app.
Inflexibility of client
Client now need to access BLL/Services by using services instead of normal objects.
More Service for Different Type of Client
Now you need to provide more service than needed. Such as WebRequestRetriever, MobileRequestRetriever instead of accessing to a mere IRequestRetriever and let the composition root wire up the rest.
Apologize if this answer boarden the topic (just realized after finished).
IMHO:
It depends on who does the injection !-
It seems you need to/expect to have an MVC or MVP architecture to be in place, where a controller or Presenter does the job of translating the UI calls to business objects ,back and forth -
Creating concrete implementations of IDataAccess, Sending it to Address class.
So that the UI is totally unaware of who is providing the data it needs, and it provides you the expected scalability.
Thanks
Tarriq
I'm learning about layered architecture at the moment and I'm wondering how to add a logging system to such a design.
Now let's say we have three layers:
Presentation Layer
Business Layer
Data Access Layer
And assume that only a higher level layer is aware of the layer one level below. For example, the Presentation Layer is aware of the Business Layer but not the other way around.
Where should you implement a general logger class?
If I implement it in a different project, it means all the layers have a dependency on a common assembly, which may or may not be good. Though this can be overcome with dependency injection.
If I implement it in the highest level (in our case the Presentation Layer), it will defy the Single Responsibility Principle.
What is a good place to implement a logging mechanism?
And after implementing it, what is a way to use such a system?
It should ideally be able to catch uncaught exceptions and save the exception description somewhere.
Where should you catch exceptions? Should they be caught in the highest layer (the Presentation Layer)? Or should they be caught somewhere else?
And what is the way to use to pass a logger to a class? Does it make sense to add a method/constructor overload to everything in the project that accepts an interface like ILogger?
As you can see I'm pretty confused about the subject, and in my current job there's no one that has any knowledge about enterprise application design / layered design, even though they are designing enterprise applications. So any help showing me the right direction will be appreciated.
Logging is a cross-cutting concern. This means that it encompasses all layers of your architecture, and it makes sense to implement it as a separate library. However, this would only make sense as an exercise, since there are already very good solutions like Log4Net, NLog, and even .NET's own TraceSources.
I tend to prefer those which support hierarchical logging (e.g. log4net). This make it much easier to configure the desired tracing level in production systems. E.g. you could set general tracing level for MyApp.SomeNamespace to Warning, but also have set a specific type like MyApp.SomeNamespace.AnInterestingClass to Debug.
I am not sure I understood the "what is a way to use such a system" part.
You use logging everywhere it is needed, in all layers of your app, in each method which needs it. I am under impression that you have an idea of centralized place where all errors are handled and logged, but these are separate things.
It should ideally be able to catch uncaught exceptions and save the
exception description somewhere.
No, it shouldn't. Loggers write stuff to logs, they don't handle exceptions. Logging is not used only for reporting errors. You also want to log the execution of your application and many internal information (but with varying tracing levels), for the sake of troubleshooting the system in production or post mortem analysis.
Where should you catch exceptions?
At all levels. Many methods in your code will be handling the exceptions relevant to current context. I suppose that you really want to know where to handle the exceptions which were not caught elsewhere - some kind of catch-all handler. For this, often it makes sense to do it in the topmost layer, i.e. in your .exe or, more generally, in the layer which contains the types which represent the application itself. There are many ways to do it - from simply registering the handlers for the unhandled exceptions (ThreadException/UnhandledException) to HandleError/Application_Error in ASP.NET MVC to using something like exception handling application block, which I personally dislike (as most of Enterprise Library).
And what is the way to use to pass a logger to a class? Does it make sense to add a method/constructor overload to everything in the project that accepts an interface like ILogger?
It depends on your implementation. It seems that you want to go down the dependency injection path. Since logger is not an essential dependency (i.e. it is not related to functional behavior of types, but to the implementation), I would prefer to handle it via property injection as an optional dependency, instead of doing it via constructor which, IMO, should be used only for primary dependencies - those which are required for the type to function properly.
However, you might not want to use DI. Then you need some other way to get to logger. One option is discussed here.
I'm using Log4Net to handle logging in my WPF application.
Currently, the logger is configured with the rest of the front-end code. I have to pass a reference to the Service layer and the Repository layer if I want to be able to use the logger in these layers (I'll actually be using StructureMap for this). This means the back-end has a dependency on the front-end and I don't like that.
I'm wondering how best to handle this? Should I configure the logger in the Repository layer?
log4net LogManager.GetLogger(string name) will return an existing logger instance if it has already been created (e.g., in another layer), so there is no need to pass logger objects around.
You do need to be aware of multiple threads/processes trying to write to the same log file at the same time. You can use the log4net MinimalLock, or try this third party solution. Neither is ideal (the codeproject one is inefficient and still hits concurrency problems). I have ended up writing my own (which unfortunately is not publicly available).
Logging is a common cross-cutting concern that I have seen handled in several different ways. The simplest method is to create a static class that lives in a common assembly that is shared by all the layers.
However, since you are using StructureMap for your IoC, a better solution would be to configure StructureMap to inject your logger class (which might be configured as a singleton, depending on your needs) into each instance created. I personally prefer property injection for such cross-cutting concern classes, so that constructors don't get cluttered, but that's a matter of preference.
I’m new to Dependency Injection and had a question/need guidance.
I had an application that used the repository pattern for data access. I used StructureMap to get the correct repository and all worked well.
I have since broken out my model (including the repository logic) into its own assembly and added a service layer. In the interest of DI the service layer class takes an IRepository in its constructor. This seems wrong to me as now all consumers of my model need to know about the repository (at least configure their DI to know which one to use). I feel like that is getting into the guts of the model.
What sounds wrong with this?
An application written to use dependency injection typically configures a single container instance where all the interface/implementation type mappings have been registered at an initialization stage of the application. This would include the registration of the repositories, services, and any consumers of the service within the application.
By resolving the consumers of the service through the container, consumers need only indicate their dependency upon the service, not any dependencies the service might need. Therefore, the consumers of the service will not be coupled to its dependencies (e.g. your repository). This is the benefit of doing dependency injection through a container as opposed to doing manual dependency injection.
If you are designing services to be consumed by other applications in the form of a reusable library then your options will vary depending on the level of flexibility you wish to offer.
If you presume all clients of your library will be using dependency injection, then you will need to provide an appropriate amount of documentation about what types need to be registered within their container.
If you presume all clients will be using a specific container (e.g. StructureMap), then you can ease the registration requirements by providing registries which encapsulate all the specific registration needs for the client.
If you wish to allow your library to be used by clients not using their own dependency injection container then you can provide a static factory which returns the service. Depending on the level of complexity, such a scenario may not require use of a container (for example, if your service is comprised by just a few objects in all). If your library is comprised of a substantial amount of components which need to be composed then you might have factories which resolve the services through their own shared internal infrastructure initialization needs.
I understand your dilemma there Dan, I too spent lots of time wrestling over that in my mind. I believe the way I decided to go forward with was one of best ways to encapsulate all of the concerns and still have easily maintainable loosely coupled objects.
I wrote this blog post specifically about NHiberante but if you look at the repository pattern in implement you can easily change the NH specific code to use your backingstore.
Creating a common generic and extensible NHiberate Repository