I want to get information on an Assembly in my C# application. I use the following:
Assembly.GetCallingAssembly();
This works perfectly returning information on the calling Assembly.
I want to share this functionality with other applications, so I include this in a class in my class library.
I reference this class library in multiple applications. When I make a call to this method from my applications, it returns information on the class library and not the application. Is there a way I can alter my above code to return information on the web applications assembly while still having the code included in the class library?
Instead of having the class library being intelligent why don't you have the caller pass an Assembly as argument to the method? So when you call the method from within some application you would pass Assembly.GetExecutingAssembly() and the method within the class library will now be able to fetch the assembly of the actual caller.
I'm not sure what you provide on top of reflections, but maybe you're abstracting a facility that doesn't need to be abstracted. Reflections already handles this, so why not let it do its job?
But if this API gives you back some useful information (such as plugging nicely into your database, etc), then maybe your approach makes some sense. But I still recommend that you refactor it:
Put this code in only one shared project/assembly, and just link that project/assembly when you need to call that functionality. Needing to duplicate code to get your job done is considered code smell.
Take an Assembly object as a parameter, rather than trying to determine the current assembly. This will allow more flexibility in case you come up with some code that wants to get data on a bunch of other assemblies, and will still allow you to pass the current assembly. (Note: Darin already made this point)
Related
I'm working with one application that that has and C# API. This program has different versions of it. But the api stays the same through its versions.
So i have written a managed code to one of its versions, and now i want to run the same code at different version of the application at runtime where i exactly know witch version of the app is running.
Question is:
Is it possible to replace assembly version and dll location at run time without writing unmanaged code using reflections?
Yes, you can use Assembly.LoadFrom to load an assembly. You can then use reflection to go thru the types of said assembly and call methods.
To avoid needing to use reflection for everything there should be a shared interface-assembly that define your api. There should also be a single entry point to the API. So you can use reflection find the class that implements the entry-interface, create an instance of this class and cast it to the interface. That lets the rest of the code use actual types.
You still need to be careful however, if there is any miss match between the interface and the actual types, you will get an runtime exception. You will not get an exception when the interface method is called (as might be expected), but when the method that calls the interface method is called. This due to the jitter resolving types when a method is compiled, and this is done the first time it is called.
I'm trying to find a way to update an Asp.net web api (.Net framework 4.5) at runtime (without recycling the main appdomain) by adding new ApiController (downloaded by another service).
I tried to use Mef and was able to load the new ApiController in the current appdomain, but I got stuck when trying to update an existing plugin (the assembly is already added to the appdomain, so I can't add the new one).
So I decided to load the plugin containing the ApiController in a separate appdomain and use MarshalByRefObject to load it from the main appdomain but it turns out that ApiController cannot be serialized.
Do you know how I could serialize it?
Do you know an alternative?
Edit:
I managed to load different versions of an assembly (in the same appdomain) if the assembly is signed, but it doesn't match my requirements.
I haven't used MEF (because it is as easy to implement its functionality from scratch, in contradiction to MAF), but this way I have some experience with bare AppDomains.
It is hard to tell much without seeing your code, but from what you wrote, it seems to me that you are confusing some things.
As you probably know and you already pointed out too, you can't actually update an already loaded assembly. Loading another version of it (having a different signature) means that you have two different assemblies loaded. The types within them will have different strong names. You could actually handle this if you want. The only way to unload an assembly is to unload the appdomain that contains it.
My problem is with this sentence:
... load the plugin containing the ApiController in a separate appdomain
and use MarshalByRefObject to load it from the main appdomain
Type (class) definition+code and instance data are two different things. Loading an assembly into an appdomain means you are loading type definition and code. Serialization comes into view when you want to transfer instance data across appdomain borders. You can't load type definition and code from an other appdomain as you wrote (actually you could but I doubt you need to). To be able to transfer instance data both sides need to have knowledge about the type definition of the instance being transferred. The serialization and the transferred in this case is managed by the .net remoting runtime.
You have two choices: either move all the instance data and have it serialized all the time or you choose MarshalByObjRef way as you said you did. Let's stay with this. To be able to work with an instance in an other appdomain, you will need to instantiate the type in the other appdomain using the activator (you can't use the new operator in this case), and get a reference to it which will be a proxy based on the type you know (that can be an interface or a base class too, not only the exact type). Reflection is somewhat limited in such a situation, even less is prepared asp.net to figure out methods of a remote object - but you could help it with proper interfaces.
So, let's imagine you have created an instance of the controller in the other appdomain, and you have a remoting reference on it assignable to an interface type that defines all methods you need to expose to asp.net. Now serialization will come into view when are trying to access the members of the controller class. Each method parameter and method return type needs to be serializable. But not the class itself, as it is a MashalByObjRefdescendant and will not be mashalled as an instance. And MashalByObjRef has nothing to do with how you are loading the assembly into the appdomain.
But wait! Both MarshalByObjRef and ApiController are abstract classes. How do you want to derive your actual controller class from both? You can't. Thus I don't think you can directly use apicontrollers from an other appdomain directly.
I could imagine two things:
1) Stay with loading the new signed version into the same assembly and make customize the routing mechanism to direct requests to the latest version (might not be still valid, but could be still a good starting point: https://www.strathweb.com/2013/08/customizing-controller-discovery-in-asp-net-web-api/).
Of course, on restart, you should load only the latest one if you don't need to have multiple versions in parallel.
2) Make a slightly complex infrastructure:
define an interface for the controller logic
create the apicontroller versionless and logicless, but capable of creating and unloading appdomains, loading assemblies into them, keep reference to the instances implementing the interface from above created in them, and directing the requests to those
be aware that you won't be able to pass some things (like controller context) to the logic in the other appdomain, you will have to extract what you need or recreate on the other side
this way you can have the logic MarshalByObjRef descendant in the "remote" appdomain and your controller ApiController descendant in the main appdomain.
I would create an interim abstract class extending ApiController with the capability of handling the above separation on its own. The rest of the application wouldn't be aware of this.
be aware of the lifetime services involved in remoting, which you can handle either by using a sponsor or overriding some methods of MarshalByObjRef.
Neither is simple approach, you will be facing some further challenges...
I have a .NET dll wrapper around a mixed (Managed/Unmanaged) type. If some crucial dll's are missing from the hard drive or their location is not entered into the path, then the type will not load resulting in a TypeLoadException("Could not load file or assembly or one of its dependencies"). This hampers xcopy deployability of any utility that consumes this class library.
I would prefer to fix this problem without instructing all clients to change client code. I hope to achieve this by running code before the type is loaded by the CLR. I have included its dependencies in a zip file which is included with the distribution.
Clients call into a static factory method.
var MyMixedTypeInstance = MyMixedType.Create();
However, since the factory method signature return type is MyMixedType, then MyMixedType is attempted loaded before any code inside the create method is executed. I have considered make the return type an interface to avoid this. But if the interface at some deals with (eg returns) a concrete mixed type, then AFAICT I'm back to square one.
I attempted stuff like using a static constructor, but it seems (as maybe all of you others know) that types exposed by the public API are immediately loaded. However, I do not know much about how the loading of types unfold, so I may be missing something obvious. I know that you can help the CLR resolve assemblies, but I do not know if this relates to a type.
Naturally, it would be possible to create a complete separate "MakeSureNeededBinariesAreInPlaceAndInPath" kind of method and demand/force all clients to invoke it prior to calling the Create() method, but I would like to avoid it if I can.
Is there for instance any attribute I can decorate the type with to intercept the type loading of the class?
I have an application ( web-service ).
I want to print some function's hints/description of it, but NOT from the DB, textfile or other prepared context, BUT from the current web-service, which is running in live mode.
I want just to copy the source code of it and then post it via web to the client for showing the real function definiton in realtime/runtime. It's important to make him always available to look the fresh changes and for NOT depending on perviously required prepared context for hints.
Are there any suggestions?
I know, that CLR metadata is easy to disassemble and may there is a way to do it for my aim, what do you think?
You can not access the code of the function in execution, but I doubt that you actually need a code of the function itself, instead you need a definition of the function.
For this you can use StackTrace class, that provides information about StackTrace at runtime.
This future you can be implemented only by embedding your classes and methods with attributes after the assembly has been built only. The logic is:
Build you assembly
On post-build execute utility which:
gets as parameters you assembly and path to source code
finds methods' and classes' definitions in source code files
using somesthing like PostSharp adds attribute to every method and class of your assembly (attribute will contain method or class code)
at runtime service will find this attribute value and will use it as you need.
I'm interested in creating a desktop application composed of modules such that the source code to those modules is embedded in the application itself, allowing the user to edit the application as they are running it and have the updated modules put into use without restarting the application. Can anyone suggest a good architecture for this?
I'm looking to use Microsoft.Net and C# for this. DLR is not an option.
Thanks!
It's not easy to suggest a good architecture for this in a short posting.
At first, i'd define a contract (an Interface) every module the user writes/modifies must implement. It should contain at least an Execute method.
Then I'd create a Wrapper-Class for these modules which:
loads the source code from a file
The wrapper compiles the file and also makes sure it implements the contract
Contains an indicator of whether the file could be compiled sucessfully
It should also implement the contract, for easy calling and handling
Then I'd have some kind of shell which contains a collection of all the module-wrappers. Any wrapper that sucessfully compiled would then let the Shell call the Execute method of the module interface.
When it comes to compiling and executing code on the fly, this link should provide all the information you need:
http://www.west-wind.com/presentations/dynamicCode/DynamicCode.htm
Well, a dynamic language certainly would have been the best fit...
You can use the types in the System.Reflection.Emit namespace to dynamically create assemblies.
However, it's going to be really painful because you'd need to load those dynamic assemblies into custom AppDomains because otherwise you'll not be able to unload them again.
This again means that you must address marshalling and assembly resolution issues related to cross-AppDomain communication.
What you are probably looking for is the concept of Dependency Injection.
Dependency Injection means that instead of having module X use module Y directly, module X only relies on an interface, and the application tells module X which implementation should use for it, e.g. using module Y.
There are several ways of implementing Dependency Injection. One is to have references to the interfaces in each of your modules, and explicitly let the application configure each of its modules with the right implementation of the interface.
The second wahy of implementing it (and probably the most useful in your case) is by using a central registry. Define all the interfaces that you want to have in your application. These are the interface for which you want to dynamically change the implementation. Then define identifications for these interfaces. These could be strings or integers or GUID's.
Then make a map in your application that maps the identifications to the interfaces, and fill the map with the correct implementations of the interfaces. In a C++ application (I'm not very skilled in C# yet) this could work like this:
std::map<std::string,IInterface> appInterfaces;
appInterfaces["database"] = new OracleDatabaseModule();
appInterfaces["userinterface"] = new VistaStyleUserInterface();
Make all modules go to this central registry whenever they want to use one of the modules. Make sure they don't access the modules directly, but they only pass via the registry. E.g.
MyModule::someMethod()
{
IDatabaseInterface *dbInterface = dynamic_cast<IDatabaseInterface *>(appInterfaces["database"]);
dbInterface->executeQuery(...);
}
If you now want to change the implementation for an interface in the application, you can simply change the entry in the registry, like this:
IInterface *iface = appInterfaces["database"];
if (iface) delete iface;
appInterface["database"] = new SqlServerDatabaseInterface();