DTSearch COM Interop - How do I expose objects to C#? - c#

I know, I'm taking a gamble here. I don't know if I can even be helped on this one at all. But, here is the problem.
The company I work for has a fully licensed, if old, developer copy of DTSearch including the C++ source. They use this in an application I'm updating. I've been told to make use of it in the C# additions to this app that are currently being worked on. However, I don't have the .NET assembly and they refuse to implement it for some reason.
So, I can easily view dtengine in the Object Browser and there are lots of lovely objects waiting for me to use them. But none of them will instantiate. Attempting it gets me
'dtengine.SearchJobClass' cannot be embedded. Use the applicable interface instead.
And there are interfaces galore, I can easily implement any of them. Trouble is, "throw new NotImplementedException" doesn't exactly get my searching done.
Does anyone have any clues?

I've used some COM objects that you have to instantiate like so:
Foo f = new FooClass();
Does the DTSearch have similar looking class names?
I also believe that COM interfaces are special and that you can instantiate a COM object by it's interface though I'm having a hard time finding good examples.
I did find this:
http://www.codeproject.com/KB/COM/COMBasics.aspx
note that if you scroll down you'll see them instantiating the Interface in a special way. I'm not saying this is a solution but it may help in your investigation of how to use the DTSearch COM wrapper in your application.

Related

How to create an object in C# which inherits from IDispatch that can be incorporated into older programs that use ActiveX

first time on SO though I've used the site a lot, I will get straight to the point.
My actual end goal is to create an object which inherits from the IDispatch interface in C# which can be used in Canvases inside of Oracle Forms Builder (Oracle Developer Suite 10g (10.1.2.0.2))
Does anyone have any resources where I can learn how to do this or where any examples of this are shown?
In order to achieve my goal thus far I went to this site : http://www.codeproject.com/Articles/24089/Create-ActiveX-in-NET-Step-by-Step
Here I got some code which allowed me to create and test an activeX object. I believe that all objects utilized by the COM structure. I then registered this using regasm and then I tried to call it. I was able to call it successful in IE.
I was about to recreate this active X object after some time; however, whenever I attempt to import it to Oracle forms I got an error like:
To me the error seems very clear, I obviously did not implement some method that oracle forms needs me to implement. What are the methods I need to implement and how should it be implemented.
Sorry for the long question, any help regarding this will be appreciated.
I suggest you start by reading this description in MSDN of the interfaces which ActiveX controls may expose.
You will need to implement at least the minimum functionality (i.e. minimal set of interfaces) to keep the Oracle Forms Builder happy. Just implementing IDispatch is not sufficient.

MAF with class inside DLL passing to host

I'm developing a MAF application which, in a DLL contains a class. The problem is, when one of the methods exposed by one of the AddIns uses this class. Example:
class A
{
Property_1
Property_2
Method_X()
}
And my AddIn has a method which use class A
MyAddIn.Set(class A);
So, with this, where must I place the DLL in the pipeline? Or how should I proceed with this scenario?
When the proyect start, the warnings of the AddInStore.Update() method throws messages like: unable to connect a part of a canalization...
So, there is an article this which says "There are many other capabilities MAF provides such as versioning, passing collections and WPF visuals, passing non-serializable types, etc.". But I can't find an example.
EDIT:
Thanks to Panos for this link about the restrictions on contracts. And after more research I've found this article which, through the Paint.NET proyect, shows how to use data types in the host without referencing.
After reading both sources, I know that this is what I'm looking for. But I can't understand it yet.
As a final petition, can someone please provide me code example? Just to finally get it.
Thanks.
You should study these guidelines on what types are allowed in the contracts assembly.
Basically you should not reference the dll you mention in the pipeline (contracts, adapters and views) because this way you can leak types from the host to the add-in. This means that you will lose versioning because all pipeline segments are referencing the same assembly. What this means is that if the add-in is referencing v.1 of the assembly and the contract is referencing v.2, both versions will be loaded and an InvalidCasrtException will be thrown.
A solution to this is to create an interface based on class A and make it a contract. Then your add-in can provide the implementation. Thiw way you will not lose versioning.
Regards,
Panos

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.

Any way to avoid creating a huge C# COM interface wrapper when only a few methods needed?

Greetings all,
I’m working on a C# program that requires being able to get the index of the hot item in Windows 7 Explorer’s new ItemsView control. Fortunately, Microsoft has provided a way to do this through UI Automation, by querying custom properties of the control.
Unfortunately, the System.Windows.Automation namespace inexplicably does not seem to provide a way to query custom properties! This leaves me with the undesirable position of having to completely ditch the C# Automation namespace and use only the unmanaged COM version. One way to do it would be to put all the Automation code in a separate C++/CLI module and call it from my C# application. However, I would like to avoid this option if possible, as it adds more files to my project, and I’d have to worry about 32/64-bit problems and such.
The other option is to make use of the ComImport attribute to declare the relevant interfaces and do everything through COM-interop. This is what I would like to do. However, the relevant interfaces, such as IUIAutomation and IUIAutomationElement, are FREAKING HUGE. They have hundreds of methods in total, and reference tons and tons of interfaces (which I assume I would have to also declare), almost all of which I will never ever use. I don’t think the UI Automation interfaces are declared in any Type Library either, so I can’t use TLBIMP.
Is there any way I can avoid having to manually translate a bajillion method signatures into C# and instead only declare the ten or so methods I actually need? I see that C# 4.0 added a new “dynamic” type that is supposed to ease COM interop; is that at all relevant to my problem?
Thanks
The most important thing (from the perspective of calling a COM method from C#) is that the methods appear in the interface in the right order. If you're not using a method, you can just declare it as void and nothing bad will happen (unless you actually call it!). This saves you from having to work out the correct signatures and define all the other types, etc. For example,
[ComImport, Guid("30cbe57d-d9d0-452a-ab13-7ac5ac4825ee"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IUIAutomation
{
void CompareElements();
void CompareRuntimeIds();
void GetRootElement();
// 50 or so other methods...
// ... define only the signatures for the ones you actually need
}
The methods should be defined in exactly the same order they appear in UIAutomationClient.h (in the Windows SDK).

Justification for Reflection in C#

I have wondered about the appropriateness of reflection in C# code. For example I have written a function which iterates through the properties of a given source object and creates a new instance of a specified type, then copies the values of properties with the same name from one to the other. I created this to copy data from one auto-generated LINQ object to another in order to get around the lack of inheritance from multiple tables in LINQ.
However, I can't help but think code like this is really 'cheating', i.e. rather than using using the provided language constructs to achieve a given end it allows you to circumvent them.
To what degree is this sort of code acceptable? What are the risks? What are legitimate uses of this approach?
Sometimes using reflection can be a bit of a hack, but a lot of the time it's simply the most fantastic code tool.
Look at the .Net property grid - anyone who's used Visual Studio will be familiar with it. You can point it at any object and it it will produce a simple property editor. That uses reflection, in fact most of VS's toolbox does.
Look at unit tests - they're loaded by reflection (at least in NUnit and MSTest).
Reflection allows dynamic-style behaviour from static languages.
The one thing it really needs is duck typing - the C# compiler already supports this: you can foreach anything that looks like IEnumerable, whether it implements the interface or not. You can use the C#3 collection syntax on any class that has a method called Add.
Use reflection wherever you need dynamic-style behaviour - for instance you have a collection of objects and you want to check the same property on each.
The risks are similar for dynamic types - compile time exceptions become run time ones. You code is not as 'safe' and you have to react accordingly.
The .Net reflection code is very quick, but not as fast as the explicit call would have been.
I agree, it gives me the it works but it feels like a hack feeling. I try to avoid reflection whenever possible. I have been burned many times after refactoring code which had reflection in it. Code compiles fine, tests even run, but under special circumstances (which the tests didn't cover) the program blows up run-time because of my refactoring in one of the objects the reflection code poked into.
Example 1: Reflection in OR mapper, you change the name or the type of the property in your object model: Blows up run-time.
Example 2: You are in a SOA shop. Web Services are complete decoupled (or so you think). They have their own set of generated proxy classes, but in the mapping you decide to save some time and you do this:
ExternalColor c = (ExternalColor)Enum.Parse(typeof(ExternalColor),
internalColor.ToString());
Under the covers this is also reflection but done by the .net framework itself. Now what happens if you decide to rename InternalColor.Grey to InternalColor.Gray? Everything looks ok, it builds fine, and even runs fine.. until the day some stupid user decides to use the color Gray... at which point the mapper will blow up.
Reflection is a wonderful tool that I could not live without. It can make programming much easier and faster.
For instance, I use reflection in my ORM layer to be able to assign properties with column values from tables. If it wasn't for reflection I have had to create a copy class for each table/class mapping.
As for the external color exception above. The problem is not Enum.Parse, but that the coder didnt not catch the proper exception. Since a string is parsed, the coder should always assume that the string can contain an incorrect value.
The same problem applies to all advanced programming in .Net. "With great power, comes great responsibility". Using reflection gives you much power. But make sure that you know how to use it properly. There are dozens of examples on the web.
It may be just me, but the way I'd get into this is by creating a code generator - using reflection at runtime is a bit costly and untyped. Creating classes that would get generated according to your latest code and copy everything in a strongly typed manner would mean that you will catch these errors at build-time.
For instance, a generated class may look like this:
static class AtoBCopier
{
public static B Copy(A item)
{
return new B() { Prop1 = item.Prop1, Prop2 = item.Prop2 };
}
}
If either class doesn't have the properties or their types change, the code doesn't compile. Plus, there's a huge improvement in times.
I recently used reflection in C# for finding implementations of a specific interface. I had written a simple batch-style interpreter that looked up "actions" for each step of the computation based on the class name. Reflecting the current namespace then pops up the right implementation of my IStep inteface that can be Execute()ed. This way, adding new "actions" is as easy as creating a new derived class - no need to add it to a registry, or even worse: forgetting to add it to a registry...
Reflection makes it very easy to implement plugin architectures where plugin DLLs are automatically loaded at runtime (not explicitly linked at compile time).
These can be scanned for classes that implement/extend relevant interfaces/classes. Reflection can then be used to instantiate instances of these on demand.

Categories