I know about AOP and Postsharp but here the constraint is I can't use postsharp and using attributes for logging is having performance overhead.
But again right now I have to put log code in everymethod, a lot of copy paste and also it is not part of method. So, my functions are doing more than one work. It is somewhat not looks good to have business logic and log together.
Is there anyway out, like to make class open ended and can add log from out side of the class or function. Or I just have to go with traditional way of logging.
Please, let me know if any further information needed. Any suggestion of good/ another way of logging is also welcomed.
Enterprise Library and Unity. You can use composition to create logging decorators around other classes that log then pass-through to the other class.
Check out msdn.microsoft.com/en-us/magazine/gg490353.aspx
Hi as Peter Ritchie told, http://msdn.microsoft.com/en-us/magazine/gg490353.aspx is good solution. You can aslo take a look at http://www.microsoft.com/en-us/download/details.aspx?id=17866 or to other DI framework like Ninject this is good one for MVC projects.
Any way this is good articale about DI perfomance http://www.palmmedia.de/Blog/2011/8/30/ioc-container-benchmark-performance-comparison.
You can create decorators for your classes, take a look http://en.wikipedia.org/wiki/Decorator_pattern
Related
I'm creating a logger for a company that has several types of .NET projects (Windows Services, ASP.NET, etc), and I was considering using log4net as my logger, but I don't want to be married to log4net, so I was thinking of wrapping it in my own assembly. I realize some developers don't recommend wrapping log4net because that would be an anti-pattern, but assuming I was going that route anyway, I had some questions:
I am planning to use the design principles mentioned in this article to design my wrapper (using factory method, interfaces, and reflection, I can simply decide which logger I want to use (whether log4net, elmah or something else) by specifying in the config file:
https://www.simple-talk.com/dotnet/.net-framework/designing-c-software-with-interfaces/
Question is:
Should I create this logger project in a separate Visual Studio solution and just use the dll in my client applications? If so, where would the configuration details for log4net go? Would that be supplied by the client application's config file? If so, is that good design? For instance, if I decided to switch away from log4net to a different logging framework, I would not only have to change the config setting to specify the new concrete logger's assembly/class name, but would also have to remove the log4net config entries (and perhaps add the new logger's config entries). Is this considered as an acceptable design approach?
Oh my goodness your timing is awesome. And that article is very relevant to me so thanks! I am doing this very same thing right now. I realized that log4net is a decent logger, but a terrible library for making a logger.
I agree with the article, in that you should not directly expose to log4net. Unless this is a small app it would be too difficult to switch later. And log4net is showing age so that may happen. I like the interface approach overall.
But, wrapping log4net it is a pain in the butt. So in doing my prototype wrapper I feel like I rewrote 50% of log4net, and discarded 25%. Some issues I found:
log4net will grab the "caller information" for you. Normally that is great. But if you wrap log4net, the caller information will point to your logger. So you will have to explicitly grab it yourself. But log4net doesn't provide a way for you to override the caller information. So now you will have to create your own fields for the caller's file, line number, class, and package. Thus, not only do you not gain the benefit here, but it is actually more work than just doing it yourself.
Log4net uses the old pre C#-4.0 method of grabbing the caller information which is slow.
Your will be unable to completely wrap log4net without wrapping the configuration. The caller has to configure the loggers either in code or in their app.config. If they do it in their app.config then they are putting log4net specific stuff in their app, so you failed to hide it with your wrapper. But if you have your wrapper code automatically perform the configuration, you just lost the flexibility of log4net. The third option is to make your own configuration, but then what good did log4net do for you? You just rewrote another piece of it.
You are stuck with the log levels that come with log4net. In our app, we want "categories" instead of "levels" which I then have to map to the log4net "levels" under the hood. Now, all the predefined log4net filters are of no use to me.
Anyone using your wrapper still has to reference log4net in their project anyway.
If your wrapper needs a way to handle errors, or pass them back to the caller, you will have trouble. log4net has its own internal error handling and you will need to hook into that and provide your own. Otherwise, errors (like a misconfigured appender) will just go out to the console. If it was designed as a library for making loggers, it would just throw the exception back up or provide a simple event.
One thing we wanted to get out of log4net is the ability to write to different outputs without us us having to write that code ourselves. Ex: I've never written to the event log, and I think log4net can do that. But it might be easier for me to rip out the Event logging code, rather than to try and wrap that. Same thing with filters.
There are some other problems I had with log4net that aren't directly related to trying to wrap it necessarily.
The code is old. The interfaces don't use generics where they should. Lots of object.
They use the old System.Collections collections. Similar to #1.
It has ifdefs for .NET 1 versus 2, and ifdefs for the obsolete compact framework. ugh.
It is designed to log strings, not structured objects. I made my own code to do so, and so did these people: http://stephenjamescode.blogspot.com/2014/01/logging-custom-objects-and-fields-with.html and http://element533.blogspot.com/2010/05/mapping-message-object-properties-to.html but this feels like basic functionality.
It doesn't support CSV and it is cumbersome to add. http://element533.blogspot.com/2010/05/writing-to-csv-using-log4net.html
It doesn't have any kind of logging "service"
It doesn't provide a way to read or parse the log.
I found it was more effort to configure the appenders than to write your own. Ex: I mapped a bunch of fields to the AdoNetAppender, but it would have taken me less time to just rewrite AdoNetAppender. Debugging a database field mapping in XML is harder than trying to debug the equivalent C# + ADO.NET code. The XML is more verbose and less type safe. This might be specific to me because I had a very structured set of data and a lot of fields.
Sorry for the really long post, I have lots and lots of thoughts on this topic. I don't really dislike log4net, I just think it is out of date and if you are wrapping it, you might be better off writing your own.
I want to log the entry of methods. In entry log I would have inputs\parameters received by the method. This has to be done for thousands of methods.
I thought of doing this logging of input parameters using C# ATTRIBUTES, since they fired before method call. (Something similar to ActionFilters in MVC)
Is that possible to read method parameters through attributes?
The concept you are looking for is called aspect oriented programming (AOP). It is a technique that allows you to "weave" in blocks of boilerplate code across your application code. Logging is a perfect example for that. You can either go the hard way and implement logging before and after each method call manually (which is on the one hand not feasible in large projects and on the other hand error prone).
Or you can use an AOP Framework that allows you to define these cross cutting functions in one place and apply it declaratively to your application code. There are several approaches to achieve this; one is to create IL after the build of the application logic and therefore integrating the aspects at compile time. A well known example for this is PostSharp. There also is a free edition that is good for the start.
BTW: PostSharp heavily relies on attributes, so you're on the right track.
Another option is to integrate the aspects at run time (keyword is interception). Most IoC Frameworks offer this. This approach is easy to use but has some downsides IMHO (weaker runtime Performance, only virtual methods can be intercepted).
Attributes are not 'fired before method call', the code that invokes a method that is decorated with an Attribute may (or may not) do something based on the presence of the Attribute.
The Attribute doesn't know the member it is applied on, nor can access it in any (straight forward) way.
I have follow an excellent tutorial about how to use Windsor and Log4Net as AOP in ASP.NET MVC
http://cangencer.wordpress.com/2011/06/02/asp-net-mvc-3-aspect-oriented-programming-with-castle-interceptors/
The article show me how to write log for every controller's action without touching any controllers
The article also state that I could do so with methods in models but didn't say how.
Can you please help me
I am the author of the link in the question, so first thanks for the kind words. Now onto your question:
It is a lot more difficult and/or impractical to use Interceptors on your models, because for Interceptors to work, you should only be accessing instances of your models through the Castle Container. See the problem?
Let's say that you have a model object called Book and you want to intercept all calls on it, you need to make sure that you never use something like new Book() and only access instances of Book through Castle. Interceptors works by proxying and would not work when you create instances of the objects yourself. This means to able to use interceptors effectively, you would need to structure your whole application around this, which I think might not be the best idea. i.e. everytime you want an instance of Book you need to ask Castle for it instead by using Container.Resolve<Book>(). I personally don't find this approach very elegant. I think it breaks encapsulation and principles of good OO design.
Interception is easy to do with controllers because all controllers are only initialized in once place, the ControllerFactory which is where we hook into. Model objects however can be initialized in different ways as they should indeed be describing your domain model.
There might be a few ways to go around this however. The first one I can think of is to use an ORM such as NHibernate which already uses interceptors in the background that you can hook into for various events such as Save, Update, or any of the method calls. Limitation will be that the interceptors will only work on models retrieved from the database.
Another option is to use a compile time rewriter such as Postsharp which will give you the means to rewrite the code after compilation. This way it is possible to add and remove additional calls to the beginning and end of each method you mark with certain attributes.
You could write Interceptors for your model exactly the same way as the Log4Net Interceptor is done.
Only use as ctor argument a contract of your model.
public ControllerModelInterceptor(IModel model)
{
this.model = model;
}
I'm attempting to develop an Interceptor framework (in C#) where I can simply implement some interfaces, and through the use of some static initialization, register all my Interceptors with a common Dispatcher to be invoked at a later time.
The problem lies in the fact that my Interceptor implementations are never actually referenced by my application so the static constructors never get called, and as a result, the Interceptors are never registered.
If possible, I would like to keep all references to my Interceptor libraries out of my application, as this is my way of (hopefully) enforcing loose coupling across different modules.
Hopefully this makes some sense. Let me know if there's anything I can clarify...
Does anyone have any ideas, or perhaps a better way to go about implementing my Interceptor pattern?
Update: I came across Spring.NET. I've heard of it before, but never really looked into it. It sounds like it has a lot of great features that would be very useful for what I'm trying to do. Does anyone have any experience with Spring.NET?
TIA,
Jeremy
I strongly recommend looking at some of the existing Aspect Oriented Programming (AOP) frameworks for .NET since they will likely accomplish what you're trying to achieve in a more generalized and maintainable fashion. Most of them are open source, so where they don't meet your needs you may be able to extend and contribute to the project(s).
More details: http://www.sharpcrafters.com/aop.net
Spring.NET, Unity Framework and StructureMap are probably your best bet. What I have done in the past is used MVC and created a custom controller factory to generate my controllers. However using dependency injection became difficult with frameworks like NinJect because of it's lack of an XML configuration (Ninject uses a fluent API). The reason it's difficult ofcourse is that you are not sure at runtime what modules you will need dependency injection for.
The three IOC containers above all have some form of XML configuration which can be modified outside of your compilation and therefore help to make your application more modular, so there would be (hopefully) no need for static initialization. The major plus being that you don't have to worry as much about thread safety.
Using a configuration file I want to enable myself to turn on and off things like (third party) logging and using a cache in a C# website. The solution should not be restricted to logging and caching in particular but more general, so I can use it for other things as well.
I have a configuration xml file in which I can assert that logging and caching should be turned on or off (it could also be in the Web.Config, that's not the point right now) which will result in for example a bool logging and a bool caching that are true or false.
The question is about this part:
What I can do is prepend every logging/caching related statement with if (logging) and if (caching).
What is better way of programming this? Is there also a programming term for this kind of problem? Maybe attributes are also a way to go?
Why not just use the web.config and the System.Configuration functionality that already exists?
Your web app is going to parse web.config on every page load anyway, so the overhead involved in having yet another XML config file seems overkill when you can just define your own section on the existing configuration.
I'm curious what kind of logging/caching statements you have? If you have some class that is doing WriteLog or StoreCahce or whatever... why not just put the if(logging) in the WriteLog method. It seems like if you put all of your logging caching related methods into once class and that class knew whether logging/caching was on, then you could save your self a bunch of If statements at each instance.
You could check out the Microsoft Enterprise Library. It features stuff like logging and caching. The logging is made easy by the fact you always include the logging code but the actual logging beneath it is controlled by the settings.
http://msdn.microsoft.com/en-us/library/cc467894.aspx
You can find other cool stuff in the patterns and practices group.
Consult http://msdn.microsoft.com/en-us/library/ms178606.aspx for specifics regarding configuring cache.
I agree with foxxtrot, you want to use the web.config and add in a appsetting or two to hold the values.
Then for the implementation on checking, yes, simply use an if to see if you need to do the action. I highly recommend centralizing your logging classes to prevent duplication of code.
You could use a dependency injection container and have it load different logging and caching objects based on configuration. If you wanted to enable logging, you would specify an active Logging object/provider in config; if you wanted to then disable it, you could have the DI inject a "dummy" logging provider that did not log anything but returned right away.
I would lean toward a simpler design such as the one proposed by #foxxtrot, but runtime swapping out of utility components is one of the things that DI can do for you that is kind of nice.