I am working on a C# project and want to make use of the UnhandledException event to catch any exceptions I may have missed in my project (hoping there won't be any but to be on the same side).
I make quite a bit of software so I want to make a class library that all of my projects will make use of so I want to have one function that does all of the initialisation stuff of all my projects without me having to copy and paste the code into each project to do the same work.
What I am wondering is if I have in the class library the unhandled exception event using the following code
AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.UnhandledException += new UnhandledExceptionEventHandler(currentDomain_UnhandledException);
Will the unhandled exception only be used from within the class library or will this event handle also be exeucted from any projects that the references the class library.
Thanks for any help you can provide.
Assuming that all of your projects are running in the same appdomain, this will work correctly. We have this exact code encapsulated in a common DLL that is shared among numerous applications.
An additional suggestion: if this is used in Windows Forms applications, you probably also want to add a handler for System.Windows.Forms.Application.ThreadException. This serves as a backstop when, for example, someone forgets to add exception handling to a control event.
It is possible to load an assembly into a different application domain, but as long as you load the assemblies (like class libraries) into the current application domain this will handle the exception.
Relationship between application domains and assemblies:
http://technet.microsoft.com/en-us/subscriptions/index/43wc4hhs(v=vs.80).aspx
For instance, Assembly.LoadFile() or Assembly.Load() will load the assembly into the current app domain.
Your code could be creating a new app domain with:
AppDomain.CreateDomain(..) , then it could load assemblies into this domain, which would not be handled by your code.
If you reference libraries in your project they will be loaded into the current app domain.
Related
I'm trying to load an assembly into a separate applicaiton domain.
I don't want to create any instances or execute the assembly. So I'm not using CreateInstanceAndUnwrap method. I just want to load the dll file (not creating any types from it etc..)
var cat = new AggregateCatalog();
pluginApplicationDomain = AppDomain.CreateDomain("pluginApplicationDomain", AppDomain.CurrentDomain.Evidence,
appDomainInfo);
cat.Catalogs.Add(new AssemblyCatalog(pluginApplicationDomain.Load(File.ReadAllBytes(plugin))));
and plugin is a relative path to the dll file.
../../Extensions/Plugins\MyAssembly.dll
This throws 'System.IO.FileNotFoundException'
The path is correct, and if I do Assembly.LoadFrom(plugin), it doesn't throw any exceptions, so I'm guessing it's not the path that's incorrect.
Other solutions all used CreateInstanceAndUnwrap, but what if the assembly and its types are black box to me? I know it impements one interface and that's it?
Load dll into another domain exception
would this work? However my method's signature doesn't match that one of CrossAppDomainDelegate
MEF is more about extensibility and it seems like you actually looking for [MAF]1. Check out this SO question. From my personal experience if your plugins going to invoke some native code (interact with hardware for example) AppDomains will not prevent crashes. It's safer to host such plugins in separate processes.
I need to implement a plugin architecture within c#/.net in order to load
custom user defined actions
data type handling code for a custom data grid / conversion / ...
from non-static linked assembly files.
Because the application has to handle many custom user defined actions, Iam in need for unloading them once executed in order to reduce memory usage.
I found several good articles about plugin architectures, eg:
ExtensionManager
PluginArchitecture
...
but none of them gave me enough sausage for properly unloading an assembly.
As the program is to be distributed and the user defined actions are (as the name states) user defined: how to i prevent the assembly from executing malicious code (eg. closing my progra, deleting files)?
Are there any other pitfalls one of you has encountered?
Have you thought about using the Add-Ins and Extensiblity framework from MS?
http://msdn.microsoft.com/en-us/magazine/cc163476.aspx
Michael
One technique is to load the additional assemblies into a separate AppDomain. Unloading the AppDomain will unload the assemblies.
You can't unload a single assembly. You can only unload a group of assemblies by unloading the AppDomain they are a part of.
This is essentially how SQL CLR works, and ASP.NET -- by having a transient AppDomain for user-supplied assemblies.
I have a web application that dynamically loads assemblies based on database configuration entries to perform certain actions (dynamic plugin style architecture).
The calls to the objects are in a Factory Pattern implementation, and the object is cached (in a static dictionary<> within the Factory) as the calls can be made many thousands of times in a minute.
The calls to this factory are made from both the main web application and a number of webservices, some in different assemblies/projects.
When I need to update one of these DLLs, I have to recycle IIS to get the DLL released.
As this has an impact on another application on the server, I wanted to know if there was a way I could release the DLL without restarting IIS?
There's absolutely no way to unload a loaded assembly other than killing the AppDomain which is basically what you are doing when you restart IIS.
You can try restarting the application pool not the whole IIS server. Maybe that will do the trick for you
If you have an assembly that you need to load and unload you will have to jump through a few hoops.
the types being loaded must derive from MarshalByRefObject
the types being loaded must derive from an interface that will be used to call them
you must build a remoting based 'loader' to isolate the loaded assembly in a new appdomain, which can be unloaded.
see http://www.west-wind.com/presentations/dynamicCode/DynamicCode.htm for a good introduction. It is a bit dated and deals with dynamically generated code but given your rep I would assume that you can extract the relevant information.
What are some guidelines and best practices for when to create new application domains within an application?
Also, what are some common uses and examples of how multiple application domains are used whithin an application?
The most common scenario I've seen is to be able to provide extensibility with a different security model than the main program.
Loading a plugin in a separate AppDomain allows two things:
You can implement a more restricted security model
You can prevent the plugin from tearing down your application if it's buggy
Another nice use of AppDomains are to load and inspect an assembly. Doing this in a separate AppDomain allows you to glean information (or run code) from a separate assembly, then unload the entire assembly from your process's space. If you load the assembly directly, there is no way to unload it. This is also useful if you want to be able to, at runtime, "upgrade" a type to a new version (ie: load a remote assembly, and reload it later).
It is recommended to create new domain when you need to host 3-rd party components within your application that are unreliable or you do not trust them (like plug-ins) or you want to be able to unload them.
A typical example is for plugin-/addin-like cases. Not only does it allow you to unload the DLL if required, it also gives you better security control over what the plugin is allowed to do.
Also, if you create temporary assemblies (code generation) which you want to unload again, this is a good way to do it. (LCG only allows implementing single methods, if you want to implement a complete class you need to emit to a "real" assembly).
My project is an application in which we load various assemblies and perform operations on them.
We are stuck at a situation where we need to add a reference to the assembly we load (which will be selected by user). So I need to add a reference to the DLL at run time.
I tried this site but here they support only microsoft DLLs like System.Security etc. I want to add a reference to a user created dll (class library).
You can't "add a reference" at runtime - but you can load assemblies - Assembly.LoadFrom / Assembly.LoadFile etc. The problem is that you can't unload them unless you use AppDomains. Once you have an Assembly, you can use assemblyInstance.GetType(fullyQualifiedTypeName) to create instances via reflection (which you can then cast to known interfaces etc).
For a trivial example:
// just a random dll I have locally...
Assembly asm = Assembly.LoadFile(#"d:\protobuf-net.dll");
Type type = asm.GetType("ProtoBuf.ProtoContractAttribute");
object instance = Activator.CreateInstance(type);
At which point I can either cast instance to a known base-type/interface, or continue to use reflection to manipulate it.
If the assembly is in another location than the current or in the GAC, just use the
AppDomain.CurrentDomain.AssemblyResolve event to deliver the assembly yourself.
If you load an assembly at runtime, it will look for all its dependencies in the current location or the GAC, and load them if found, else error.
The Composite UI Application Block facilitates the design and implementation of your client applications in three areas:
It allows your application to be based on the concept of modules or plug-ins.
It allows developers with shell expertise to build components that hide user interface complexity from the business logic development.
It facilitates development using patterns for loose coupling between modules.
For WPF: Take a look at Prism: patterns & practices Composite Application Guidance for WPF and Silverlight site It does the assembly loading you require and actually uses Unity internally as it's IoC container.
For non WPF: Take a look at Smart Client - Composite UI Application Block
Or alternatively: Try any of the IoC containers like Castle Windsor, autofac, unity, etc.