I have a DLL which will be used from a non-.NET application, so it doesn't appear that it will read a config file.
I've read solutions where you can code custom solutions to explicitly read the config from a DLL, but I don't see how to get the logging component to read that.
The config page for logging in System.Diagnostics claims that you can set everything from code. I have found how to create and add a listener.
static LogFactory() {
TextWriterTraceListener myListener = new TextWriterTraceListener("C:\\Logs\\app.log", "myListener");
Trace.Listeners.Add(myListener);
myListener.WriteLine("Test message.");
Trace.WriteLine("Another test");
myListener.Flush();
}
The file is created but nothing gets written to it, either from this explicit write, or from any call to logging in the app.
TRACE is set in the build options.
It's not clear from your question how exactly is the DLL going to be used from the non-.NET application and how they are communicating with each other, but ideally the DLL would not have its own log... It would write to the log of the main app that is consuming it.
That means you would design your DLL in such a way that the consumer can provide you with a way to write to their logs (e.g. by passing an ILogger interface that are common/known by both DLL and host app, or at least a delegate of some kind e.g. Action<string>) through an agreed upon bootstrapping method that the host app would call as part of the bootstrapping of the app.
If you do decide to have a separate logging for the DLL without cooperation with the host app, then you could try using a ModuleInitializer which is a special function you can add to your .NET assembly that runs when the assembly is loaded for the first time.
As of this writing, an easy way to add ModuleInitializers to assemblies is through a Fody plugin called ModuleInit.
As for emitting the logs from within your DLL (regardless of the approach above), you might want to consider Serilog or NLog which offer a much more rich logging capabilities compared to Trace.
Related
We have c# application with several different modules. We are using log4net for logging. What should be done to log the messages:
Create a centralized logging project: The application classes to use centralized logging project's dll's static methods to log the messages. So, no class in application creates the logger, all logging requirements to be fulfilled by this dll OR
All types in the application itself creating their own loggers: Easy to check which type generates which message, easy to manage different type of logging requirements i.e.we can throttle logging behavior of each type independently, like one class logging ALL logs but other only loggin ERROR.
What is the preferred practise?
The approach2 has its own benefit but approach1 looks clean as each class would no longer be responsible for calling "GetLogger(typeOf(className))".
What is the recommended way?
It really depends on the usecase, when making a library it can make sense to use method 1. However when making a complex program method 2 will help you to manage different logger independently. Method 2 will give the also the option to log all in you project like method 1 does. However method 1 does not support differing on logger. So method 2 seems a better choice in most cases.
I have a web application that refers to a DLL. This DLL has certain config values, which are normally part of the web.config.
There is a requirement to invoke this DLL under different configurations, from the web application. The DLL is third-party and cannot be changed.
Have tried the below and failed.
Have different copies of DLL (named a.dll, b.dll) and load it by reflection. The problem here is that it’ll still look for the web.config and not the a.dll.config. Also, since same Types are referenced in the main program as well as the reflected assembly, it goes crazy.
Change the config on the fly using AppDomain.CurrentDomain.SetData("WEB_CONFIG_FILE", #"Config\Path") and switch it back after the call. The problem here is that after the first time, it doesn’t load the config section again even if I switch.
Use ConfigurationManager.RefreshSection(#"configuration\mysection") to force a refresh. This doesn’t seem to work and people say this call is buggy in .NET
I've seen some recommendation to update the web.config, but this may not be a good choice for me because the switching of values would happen fairly frequently
Is there anything else I can do?
Host the DLL in a separate process and communicate using COM (or .Net remoting or a web service or similar).
I.e. create a host process a.exe using C# (say) which exposes classes as COM objects, the classes in turn calling the DLL methods/classes. Register as COM objects.
Then create b.exe the same (but with different CLSIDs).
You can now have different configuration files for a.exe and b.exe (in different folders), yet both can use the DLL services.
You could also do something similar by having two internal web apps and using SOAP or something to talk to them.
But the bottom line is if the DLL works on web.config, you have to put at least one of them into a separate process in a separate folder.
I need to create a Error logging project from scratch in C#.
I would like to save to a file with several levels, this logging project I am taking as an assignment from which I can learn many things and want to build it as small loggin utility for now.
I saw few loggin project which has singleton pattern and a config file having some entries and also in the consuming application config - some references of logger proj interface are there
can some one please give me an idea as how can I create a new logger
proj from scratch and what is the purpose of having entries in
config ?
pseudo code for logger project or any link
Thanks in advance.
Instead of implementing your own logging mechanism you may want to check whether existing components are an option. For example log4net is a frequently used framework that people use for .NET based projects.
Also, the Logging Application Block from Microsoft:
http://msdn.microsoft.com/en-us/library/ff632023.aspx
http://msdn.microsoft.com/en-us/library/ff664569(v=PandP.50).aspx
There are several key elements you need to consider before making one from scratch. Just to name what comes to my head :
How do you want to log? Do you want to save logs to a file, in a database, to send mails, just to have the logs shown in a console?
If you persist the logs, do you want to log everything, forever, or you want a "rolling" X lines to be kept, the rest discarded?
Do you want to have several level of logs? For example, you could log some things Info, Warning, Error, Critical Error, etc.
Do you want your logging library to support custom formatting for the logs?
As for the question about the config, it's really something you want to do. If you're talking about the app.config files, it allows you to can change the configuration of your application without rebuilding it. It can also provide some default parameters the user can override. By user, I mean another developer using your library.
I'm creating a Service for my organization that will be installed on hundreds of computers. The Implementation of it may need to change over time. After watching and read a bit about MEF I'm still a little lost. Is MEF a good soulution for say if I wanted to Drop a dll into the service folder and have that service pick up the changes?
I have done quite a bit with MEF. Yes, MEF will do what you're looking for, with a caveat...
You can discover and load in a new DLL at runtime
However, it loads into the same App domain as your main application so,
You can't unload or change the DLL without restarting your application
If that last point is a problem, consider MAF (although it's much heavier). But in MAF, it will load your extensions into a separate app domain.
Your other option is just to spawn off another process to handle the request, and pass command line parameters to it.
if you are using VS2010 i recommend you try first Click Once. It gives you the setup.exe but also gives you an HTML file (and other files), wich you can upload to an IIS server or an FTP site, or even to a shared folder over your local network. The thing is, when you configure your deployment you can tell the installer to auto-update all clientes directly from the site (the HTML file, ftp or lan shared folder). When user starts the application it will connect to the site and ask for an update if it exists, and if it does, the application will self-update. If you want to deploy an update, you only need to upload again the HTML file and all other files in the folder.
Check out this links:
http://msdn.microsoft.com/en-us/library/ms953320.aspx
http://weblogs.asp.net/shahar/archive/2008/01/29/how-to-use-clickonce-to-deploy-your-applications.aspx
Happy coding ;)
I am no expert about MEF. Documentation says Mef is all about making plug-in based systems. so your system expects some interfaces and MEF makes easy to import classes implemented these interfaces to your system.your case seems suitable for this. MEF has directory catalog and by using catalogs you can import types/dlls runtime.
How do I get a MEF Directory catalog looking at the same directory for both the Servicelayer and DAL?
I think you can do this if you have your service logic in a separated class library and you got the needed contract interfaces in another class library. Then you can create a directory catalog and import your service implementation with MEF (you only need to reference to the contract interfaces assembly). Then you can pick up the new dll/service implementation if changed. You only need a directory watcher (FileSystemWatcher), then you have to call your catalog's refresh method when directory watcher fires. In theory it should work, but it's just an idea. :) Anyway, hope this helps.
You could also look into Prism. From what I understand, they are two different frameworks to do pretty much the same thing. Prism allows you to create modules by having a class in a dll that implements the IModule interface. You can just drag and drop dlls into a folder this way just like in MEF. You can statically or dynamically load modules, and do a bunch of other things I don't even know about.
Prism also has other features bundled with it, i.e. the Unity dependency injection container (which I like to call "The Magical Black Box"), a neat event and command system, etc. I'm sure MEF has all these things too.
I am doing something unusual.
I have an application, it runs as a windows service.
what it does is that, it monitor one folder, when ever there is some new file put into that folder, the application will do something to the file.
Whenever there is an error when processing one file. I need to create a text file, and put the error/exception information into that text file. (later i can do something with this file)
so there is something like this
FileWatch, when there is a new file, do following :
try
{
processing file
}
catch(Exception ex)
{
MyLogger write exception message into one new text file
}
So far how i did it is that. I create a class for example MyLogger, whenever i new one MyLogger, it creates a text file (the name matters, need to be a specific format), and there is one method in side MyLogger "WriteError(string message)", it writes text into that file.
Since i used log4net in my application. Do you think i should modify my logger, to extend some class from log4net, so that i can get some benefit? (not sure what kind of benefit i will get, but log4net is a good logging framework, the way it handle text file might have thing that i do not aware)
Thanks
log4net or any other generic logger is helpful if
1) you want to have a consistent logging facility in many places across your application; and/or
2) you want the ability to customize logging format, level and so on.
From your description it sounds like there is a single point in your app where you need to log the exception in a specific way. If this is correct, you will probably gain no benefit from creating a custom logger - just write a method that logs exception to a file in the way you need.
If I misunderstood you, and there is a need for generic logger (that is, either 1) or 2) above is true), extending log4net by inheriting a logger or creating a wrapper is fine.
I've created log4net wrappers before. I find it handy to start this way as you don't always know what the logging requirements are at the start of a project. My rule has been that the log4net library can only be referenced from my own "logging" namespace. This way, the application code only calls the wrapper, and the wrapper is the only point of contact to the log4net functionality.
In the long run, it's probably worth investing in building your own logger. If you encapsulate log4net properly, you should be able to make this upgrade rather easily, without having to change your code.
Why not use Trace Listeners from the .NET framework? They provide many of the benefits of a logging network, without the need to incorporate an external framework.
Benefits include centralized log management and the ability to direct the output logs to one or more sources such as a console window, text file, or the Windows Event Log.
You should spend some time creating your own logger that does exactly what you want. This would be the best way. Is also fairly easy and you have full control on the customization so you can make the output look and feel as in log4net. You could Google for logging sample and start modifying that one.
I am not sure if I would use a log framework for this purpose. I have the impression that writing this text file in the exception case is part of your business process. Logging serves a different purpose that can be turned off without affecting business processes...