Where should I store Logger code to reduce dependencies? - c#

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.

Related

How to use dummy class for external API at runtime (configurable)?

I need to fetch data from an external API, only accessible via VPN.
The development/test machine will not always be able to connect to the VPN.
The desired behaviour is to use two different implementations (one that calls the actual external API and one that acts as the real thing but returns dummy data). Which implementation to use will be configured via a flag in web.config
I've tried the IoC containers StructureMap and Unity and they both did the job but they only seem to be applicable for MVC, I'm looking for a generic solution that also works for web forms. And also, isn't it a bit overkill to use them for this isolated design problem!?
Is there a design pattern or best practice approach for this particular scenario?
IoC / dependency injection sounds like the correct approach, but you don't necessarily need a container for a simple scenario. The key is to have classes that depend on the API reference an interface IAPI, and pass it the actual implementation RealAPI or FakeAPI.
public class SomeClass
{
private readonly IAPI _api;
public SomeClass(IAPI api)
{
_api = api;
}
}
Now you should be able to switch out the implementation easily by passing a different object to MyClass. In theory, when you're using an IoC approach, you should only need to bind the interface to the implementation once, at the top level of the application.
isn't it a bit overkill to use them for this isolated design problem!?
They probably are. Those IoC containers only help you when you wrote loosly coupled code. If you didn't design your classes according to the SOLID principles for instance, those frameworks will probably only be in the way. On the other hand, which developer doesn't want to write loosly coupled code? In other words, IoC container solves a problem you might not have but it's a nice problem to have.
StructureMap and Unity [...] only seem to be applicable for MVC
Those ioc frameworks can be used in any type of application (as long as it is written in loosly coupled way). Some types of applications need a bit more work to plug a framework in, but it's always possible. StructureMap and Unity might only have integration packages for MVC, it's quite easy to use them in ASP.NET Web Forms as well.
Is there a design pattern or best practice approach for this
particular scenario?
What you're looking for is the Proxy pattern and perhaps the circuit breaker pattern.

How to handle circular dependency of logger service

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.

StructureMap DI on Model Assembly

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

Using delegates or interfaces to decouple the logging - Best practices - C#

My solutions has several projects which includes several libraries and one project for UI. Currently it is a windows forms application and I use log4net for logging. This UI project has only reference to log4net and this project maintains the configuration files. But I would like to log from my libraries as well.
Usual method for doing this is to wrap the logging calls behind an interface. Create a common project something called utilities and add this interface to this project. Now this project can be used in all the projects and can use this interface for logging.
I am thinking about an alternative design which involves passing delegates and reducing coupling and avoiding unnecessary interfaces.
Consider following class is one from my library.
public sealed class Foo
{
Action<string> log;
Action<string, Exception> logException;
public Foo(Action<string> log, Action<string,Exception> logException)
{
this.log = log;
this.logException = logException;
}
public void Work()
{
WL("Starting work");
WL("Completed step1");
.........
}
void WL(string message)
{
if(log != null) log(message);
}
void WL(string message, Exception exception)
{
if(logException != null) logException(message, exception);
}
}
Now from the calling code, I can easily pass the logging method. Something like
Foo foo = new Foo(message => Console.WriteLine(message),
(message, exception) => Console.WriteLine("{0},{1}", message, exception));
foo.Work();
Used a console for explaining, in reality I will use the logging code here.
1 - Do you think this as a better solution? I think this is better as this is more loosely coupled.
2 - Is there any other better solutions available?
This is the only related question I have found here
Any thoughts...?
Don't use delegates if there are multiple signatures flying in close formation. All you're doing is avoiding defining classes and interfaces that would be meaningful. log4net provides an ILog interface which is an excellent example of a simple wrapper interface you can pass in.
If you're going to use a logging framework, especially log4net, don't wrap it and don't create a single global (static OR singleton) entry point. I've written about this before, and you may be interested in the question about best practices as well.
I have a thin layer that exposes a logging API very similar to Log4Net, that uses a provider-model design pattern to allow you to plug in any suitable logging framework. I've implemented providers for:
System.Diagnostics.Trace
log4net
EntLib
This means I can use logging throughout all my apps without any direct dependency on a specific logging framework, and users of my components can plug in their own favorite logging framework.
My advice is to add a reference to log4net to all your projects but leave the logger configuration in the UI project. This still leaves you with the flexibility to define different logging levels on a per assembly basis. Logging is such a low level activity and log4net is such a mature product that I wouldn't spend any time trying to come up with a clever solution just to satisfy "best practices". I might even argue, over a beer or two, that referencing log4net is no different than referencing System.Core.
Unless you have different pieces of code using different logging frameworks, I'd have a singleton LogDispatcher or something similar that all code which would try and log would call into, perhaps passing in a message level to determine the correct logging method. This prevents the delegates for logging from needing to be passed around the entire codebase, and centralizes all of the code which is responsible for the logging policy.
Another approach is to use a framework like Log4Net. Even if you don't end up using it, their design is a good one to base your own logging on.
Google for "AOP logging".
Here's some chat about this from Ayende.
Quoting Jon S. "Simple is almost always better than clever" - IMHO your use of delegates looks more of the latter.
If you want the library projects to log, they should setup-and-use their own logger. I'd not ask clients to pass in a logger (object or interface) - which then travels all the way deep down the type dependency graph. It just pollutes the interface a bit with unnecessary logger object/interface/delegate etc. parameters.
If you're using Log4XXX frameworks, I believe it emphasises the concept of "hierarchical logging architecture" (the names they come up with in s/w ;), where each type/class can maintain and write to its own log file. If the ctor of Foo creates a logger internally, I'd like that. And since it is configurable, specific clients may change the configuration files to redirect the output elsewhere too.
So your problem is one I will soon have to commit to a solution for. The defacto answer is "Use Injection" but in this case it's less inversion of control and more expansion of dependencies. I think your close, so here are my thoughts.
The Pros of your solution
There is no need for additional references by your class or the assembly it's in. Because your using Actions with common types, those references are likely already present.
The benefit of that is that is that 100% of the implementation of logging is left to the assembly that injects your actions. So if you add log4Net of nLog the only reference to it will be where it is implemented. So if you wanted switch later, only that assembly would have to be updated.
The converse of that is if you just inject a chosen logger into each class. That means you have to add a reference in every project to the logger. Even if the interfaces are named and implemented the same, you have to have the reference for it to resolve. In solutions where you have more than 3 projects that can be costly, and you have the same cost any time you would switch loggers.
Possible Improvement
In that lies the beauty of your solution. However it could be improved. I find that when injecting things of similar function or "aspect" it can make sense to put them into an object and inject that instead. You could create interface with both of your actions and inject concretes that implement whatever library you want. This would, again, leave the only reference to the logging library to one project/assembly with only the cost of having to add a reference to your interface to the rest.
Hope this helps and good luck.

Not understanding where to create IoC Containers in system architecture

Say I have the following 4 .net assemblies:
Winforms UI
Business Logic
SQL Server Data Access (implementing an IRepository)
Common Interfaces (definition of IRepository etc.)
My business logic (2) makes calls to the data access layer (3) through IRepository (defined in 4) using constructor dependency injection. However when I ceate a business object I need to pass in an actual repository. I do this by having a singleton class in my business logic layer return the currently in use concrete object implementing IRepository. I am coming to the conclusion that this is a bad thing, as my business logic layer now has to reference 3 as well as 4.
I think I need a IoC Container but the question is where I create/put it as it seems that wherever I create this (1 - UI)? will also need to hold a reference to 3 (SQL Server Data Access). Am I not just moving the problem rather than achieving actual decoupling?
Do I create the IoC Container in the UI. Or expose it through another new assembly.
(I'm using C#, .net 3.5 and AutoFac)
Thanks.
IoC container generally should be created in the host project (application entry point). For the Windows.Forms application that's the exe project.
Generally in simple solutions (under 10 projects), only a host project should have a reference to IoC library.
PS: Structuring .NET Applications with Autofac IoC
When registering components there are several possibilities:
Registration in code:
directly
Problem: you have to reference everything ( you are here)
indirectly
Problem : to find out what has to be registered
Solution:
use attributes
use marker interface as IService
use conventions (see StructureMap)
Registration with configuration file:
let the container do everything
read the file yourself
Top level is a way to go (UI, as Rinat said).
Now as for references, simplest way is just to go over all assemblies in the current folder and use some convention to get the services out. Attributes work fine, putting registrar classes in each assembly works fine, whatever suits you. The code for extracting everything should probably be in a separate assembly, unless your IoC framework already does that.
The module distinction and the "scopes" defined by the modules exist mostly at compile-time. In the run-time it's all one big mess ;) This is used by most IOC containers and they don't really care about where they are located. The IoC container for a web-app will typically be created at the outermost level (very close to the web-container itself).
It's true that you could create it anywhere, but I'd introduce an extra layer, let's call it 3.5.
Your current 3 would be where your IoC resides for Data Access - this would become a wrapper for your actual DAL. Based on your config, 3 would create either a mock repository or a concrete one.
So 2 still references 3, but it's just an interface to the actual DAL which is configured through your IoC framework.
Alternatively, you could roll your own 'el-cheapo' IoC - change your Big Ugly Singleton to a Static Gateway - Abstracting IoC Container Behind a Singleton - Doing it wrong?

Categories