Are COM objects dynamic or static - c#

I am trying to make a sort of proxy, and I am wondering whether COM methods and properties are static or dynamic. In other words, does .NET call the com object and tell it which method it wants executed, and then lets the com object pretend it has executed it (the way DynamicObject lets you do in .NET, just return true for TryInvokeMember without doing anything), or does .NET actually go and call the COM method directly (static)?

It sounds like you're asking the difference between early binding (static) and late binding (dynamic). C# supports both.
Early binding requires you create an Interop assembly using a tool like TlbImp.exe to generate a proxy to the COM object, which calls the interface methods directly.
To use late binding you can use either reflection (messy) or the dynamic keyword to bind the method calls at run-time.
However, the COM object will not "pretend" it executed a method you ask for - if the method does not exist, you will get a run-time exception.

Related

C# connect with com-object

Is there in C# connect to COM-object and use contents of com-object such as in the Builder c++:
CreateOleObject("some.someClass");
(OLE C # seems to be not supported, except OLEDb, but it is not the current case in my opinion)
I know I can add a link -> COM -> Seeking a registered com-object.
But it does not fit.
Normally, if you need to use a COM object in C#, you would add it as a Reference, and select the registered type library. That will generate an Interop Assembly, after which you can use the COM object just like any other C# class.
Alternatively, you can run the .NET utility tlbimp by hand, which has roughly the same effect but gives you slightly more control.
If you really need to create the object dynamically, without knowing anything about the type ahead of time, you can use the dynamic keyword and the Activator class to create a dynamic instance of a type. The code would look like:
var comType = Type.GetTypeFromProgID("some.someClass");
dynamic obj = Activator.CreateInstance(comType);
This will defer all type checking on obj until run-time, behaving much like VBA would.

Using DLLs in VBScript

I've compiled C# code into a DLL, but have little experience with them. My C# code contains a class HelloWorld with a static method Print(). I'd like to use this DLL in VBScript to call the method Print(). I know this is base, but I'm using this as a test for a larger scale project that will be compiled to DLL in the end. What's the declare look like for that and how would the method call look?
Important: Both methods will work only if the DLL exposes a COM interface.
If your dll is registered with the system, use CreateObject with it's ProgID.
Set myObject = CreateObject("MyReallyCoolObject.HelloWorld")
myObject.Print
If your object is not registered on the system, use GetObject with a path to the file containing your object. Make sure your object exposes the proper interface. (The second parameter is optional. Here you can provide a class name if your object exposes more than one.)
Set myObject = GetObject("C:\some\path\helloworld.dll", "appname.HelloWorld")
myObject.Print
I think you might be looking for Registration-Free COM. This SO answer regarding the Microsoft.Windows.ActCtx should help specifically for VBScript.
Keep in mind that COM doesn't support static methods, so you'll have to make your Print method into an instance method.
How to call a .NET DLL from a VBScript

Generic method to wrap a function

Say I want to wrap a function in another function, so to add some functionality to the wrapped function. But I don't know the return type or parameters on beforehand as the methods are generated as a web service proxy.
My first train of thought was using Func<T>. But some functions might return void, in which case Action<T> would be more appropriate.
Now my question: is there a nice generic way to achieve this? Is there some pattern I need to look for?
Well, the Facade Pattern comes to mind... It's not a very automatic way of doing things, but it works. You basically just put another interface in front of the proxy and call that instead. You can then add any functionality that you desire.
Another way to approach this is with aspect oriented programming. I've used PostSharp (when it was free) to do this this in the past. You can do things like add Pre / Post processing in the function by adding an attribute to a method / property. The AOP components then use code weaving to rewrite your IL to include the code that you've referenced. Note that this can significantly slow the build process.
As you say "I don't know the return type or parameters on beforehand", I think a Dynamic Proxy is what you
need.
Unfortunately, I know about the Dynamic Proxy in Java only. But I am sure, there is something similar for C#.
Try Googling "Dynamic Proxy C#".
For example, there seems to be an implementation for C# here: http://www.castleproject.org/dynamicproxy/
So, what IS a Dynamic Proxy?
From the JavaDoc http://docs.oracle.com/javase/1.3/docs/guide/reflection/proxy.html#api:
A dynamic proxy class is a class that implements a list of interfaces specified at runtime such that a method invocation through one of the interfaces on an instance of the class will be encoded and dispatched to another object through a uniform interface. Thus, a dynamic proxy class can be used to create a type-safe proxy object for a list of interfaces without requiring pre-generation of the proxy class, such as with compile-time tools. Method invocations on an instance of a dynamic proxy class are dispatched to a single method in the instance's invocation handler, and they are encoded with a java.lang.reflect.Method object identifying the method that was invoked and an array of type Object containing the arguments.

Force .NET type to instantiate as COM

Is it possible to force a COM Visible .NET assembly to instantiate as System.__ComObject, rather than it's .NET type? The reason I ask is, part of my app uses 3rd party COM objects, but some of those, when written in .NET, get instantiated as their .NET types and break the object handlers I've created. I have no control over methods used to create the COM objects. Currently I'm using the following to create the objects.
Type comType = Type.GetTypeFromCLSID(objectGUID);
comObject = Activator.CreateInstance(comType);
Thanks!
Actually, no.
The COM activation of managed objects is done in the same AppDomain as the caller. IMHO, This is a nasty issue with COM interop in .NET. There are several questions here on SO with all sorts of attempts at making this work. I can attest that I've tried most of these to no avail. Your COM API provider SHOULD be producing a PIA (Primary Interop Assembly) to ensure forward type compatibility. If they are not, you are going to have some nasty issues.
The only workaround I'm aware of as a client is to only use the 'object' type. Everything would need to go through reflection. Some things you still can't do. For example, you would not be able to implement an interface.
I havn't a clue why this works this way. It's caused me no end of problems producing a viable api for both unmanaged and managed code.

Return object from C# to Silverlight via COM

I have made a C# COM Visible class that I can access via the
dynamic com = AutomationFactory.CreateObject("MyCom");
function in Silverlight and I am able to return basic datatypes (ie string, int..). So far so good :).
But now I would like to return an object over the COM connection and that proved to be quite difficult. I can return an object and place it into a dynamic variable and from there access the object members, but I can't cast the data to my desired object type.
Questions:
1. Is there a way to cast a dynamic variable to my desired class.
2. Is there a way to make the COM object return an object of my desired class?
The answer to both your questions is: No.
There is no interop between the full version of .NET installed on a client and the Silverlight version of .NET.
The best you can do is create wrapper class that accepts the dynamic and delegates its members into the dynamic.
If you want to re-use code that consumes this .NET object in both full .NET and Silverlight then define the object using an interface. Have the original class implement the interface and have the wrapping class also implement the interface.

Categories