[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

microsoft.public.dotnet.framework.interop

Activator.CreateInstance of a locally defined interface, but implemented in an external .net assembly

Bob Eaton

5/11/2007 8:16:00 AM

I have the following code in my .Net DLL (call it, assemA.dll):

// assume that strProgId is something like: "FooNameSpace.BarClassName"
Type type = Type.GetTypeFromProgID(strProgId);
IFoo rIFoo = (IFoo) Activator.CreateInstance(type);

The IFoo interface is also defined in assemA using an interface statement:
[Guid("42099864-FAAC-SOMEGUID")]
public interface IFoo
{
....
}

And several implementations of IFoo are implemented in assemA.dll as well.
e.g.:
public class CFoo : IFoo
{
...
}

[Aside: the reason for using an interface rather than just the class
implementation directly AND for using Activator.CreateInstance to create it,
rather than just 'new', is because some of the implementations of IFoo are
from MFC/ATL (COM) servers. So sometimes the object created--which gets
casted as an IFoo interface above--is a .Net implementation and sometimes an
external COM implementation]

Since the code that calls CreateInstance above and casts the result as an
IFoo is shared, assemA is installed on users' machines in the global
assembly cache where there is the potential for it to reside "side-by-side"
with different versions of the same assembly. So, C:\Windows\assembly might
have assemA.dll v2.5 and v2.6 at the same time.

Now comes the problem: If one of the client applications was built against a
reference to assemA.dll v 2.5, it will correctly load v2.5, but when I
create one of the implementations of IFoo based on its ProgId, that seems
like it might be a COM interop instantiation rather than a .Net
instantiation. Since COM instantiations will always (I think) go to the
newest implementation, (I think) it will try to get the version of CFoo
implemented in the assemA.dll v 2.6.

The glitch is that even if IFoo does not change (nor does its GUID), since
IFoo is defined in both versions of the same assembly, the v2.5 of the
assembly cannot for some reason cast an implementation of IFoo from the v2.6
assembly using what it knows about IFoo in the v2.5 assembly... I think this
is true, because the call to CreateInstance is throwing an exception that
says, "Unable to cast object of type 'SomeNameSpace.CFoo' to type
'SomeNameSpace.IFoo'.

Does anyone know a) if this situation is accurate as I describe it (i.e. am
I on the right track assuming its a mismatch of some time based on the
different assembly versions), and b) if there's a solution?

Thanks in advance,
Bob



4 Answers

(Mattias Sjögren)

5/11/2007 5:38:00 PM

0

>Does anyone know a) if this situation is accurate as I describe it (i.e. am
>I on the right track assuming its a mismatch of some time based on the
>different assembly versions), and b) if there's a solution?

You can use a <bindingRedirect> element in the application
configuration file to redirect all references to assemA v2.5 to v2.6.


Mattias

--
Mattias Sjögren [C# MVP] mattias @ mvps.org
http://www.msjogren.n... | http://www.dotneti...
Please reply only to the newsgroup.

Bob Eaton

5/11/2007 5:55:00 PM

0

Mattias,

Thanks for the suggestion. Unfortunately, I'd have to do this for all
potential client applications, but that can't be reliably predicted.

What do you think about this possible solution:

I define the interface, not in the .net assembly (which then creates a
"managed interface" and gets it tied in with a specific version #), but
rather in a COM/ATL server. Then in my .Net class that refers to it, I use
the interface attribute ComImport.

Will the CLR binder then try to limit it to the specific version if it's not
a managed interface and/or defined in a .Net assembly?

Thanks,
Bob


"Mattias Sjögren" <mattias.dont.want.spam@mvps.org> wrote in message
news:ORlCaL$kHHA.3656@TK2MSFTNGP06.phx.gbl...
> >Does anyone know a) if this situation is accurate as I describe it (i.e.
> >am
>>I on the right track assuming its a mismatch of some time based on the
>>different assembly versions), and b) if there's a solution?
>
> You can use a <bindingRedirect> element in the application
> configuration file to redirect all references to assemA v2.5 to v2.6.
>
>
> Mattias
>
> --
> Mattias Sjögren [C# MVP] mattias @ mvps.org
> http://www.msjogren.n... | http://www.dotneti...
> Please reply only to the newsgroup.


(Mattias Sjögren)

5/11/2007 10:17:00 PM

0

Bob,

>Thanks for the suggestion. Unfortunately, I'd have to do this for all
>potential client applications, but that can't be reliably predicted.

In that case maybe you should look at using publisher policy for
assemA to do the same kind of binding redirect.


>What do you think about this possible solution:
>
>I define the interface, not in the .net assembly (which then creates a
>"managed interface" and gets it tied in with a specific version #), but
>rather in a COM/ATL server. Then in my .Net class that refers to it, I use
>the interface attribute ComImport.
>
>Will the CLR binder then try to limit it to the specific version if it's not
>a managed interface and/or defined in a .Net assembly?

I don't think that will help. As long as both the client and the
implementing class are managed code, the managed type identity rules
apply (type name + full assembly name). COM identity rules (based on
IID) only apply when the implementing class is native.


Mattias

--
Mattias Sjögren [C# MVP] mattias @ mvps.org
http://www.msjogren.n... | http://www.dotneti...
Please reply only to the newsgroup.

Bob Eaton

5/12/2007 1:35:00 AM

0

I'll look into Publisher Policy.

What do you think about "ComCompatibleVersionAttribute"?

Right now I use a fixed GUID, which I would have thought would have told the
CLR binder that the interface in all assembly versions which have the same
value would be identical, but apparently it doesn't.

Anyway, the help for ComCompatibleVersionAttribute says that it has no
affect if you use the GUID attribute. But since it also suggests that this
attribute can be used to "Indicate to a COM client that all classes in the
current version of an assembly are compatible with classes in an earlier
version of the assembly", I wonder if this will solve my problem? i.e. get
rid of the GUID and start using ComCompatibleVersionAttribute?

On the other hand, it isn't the "COM clients" that need this information,
but rather the CLR binder... so maybe not...

Thanks,
Bob

"Mattias Sjögren" <mattias.dont.want.spam@mvps.org> wrote in message
news:usi9TnBlHHA.5048@TK2MSFTNGP04.phx.gbl...
> Bob,
>
>>Thanks for the suggestion. Unfortunately, I'd have to do this for all
>>potential client applications, but that can't be reliably predicted.
>
> In that case maybe you should look at using publisher policy for
> assemA to do the same kind of binding redirect.
>
>
>>What do you think about this possible solution:
>>
>>I define the interface, not in the .net assembly (which then creates a
>>"managed interface" and gets it tied in with a specific version #), but
>>rather in a COM/ATL server. Then in my .Net class that refers to it, I use
>>the interface attribute ComImport.
>>
>>Will the CLR binder then try to limit it to the specific version if it's
>>not
>>a managed interface and/or defined in a .Net assembly?
>
> I don't think that will help. As long as both the client and the
> implementing class are managed code, the managed type identity rules
> apply (type name + full assembly name). COM identity rules (based on
> IID) only apply when the implementing class is native.
>
>
> Mattias
>
> --
> Mattias Sjögren [C# MVP] mattias @ mvps.org
> http://www.msjogren.n... | http://www.dotneti...
> Please reply only to the newsgroup.