Interface question

C

Chris Dunaway

I have created an Interface called IClientModule in a class libarary and
have compiled the library to a .dll.

In my main app, I scan a folder for .dll's and load each one that
implements the interface. For each one that is loaded, it is stored in a
collection object which is an instance of a typed collection class called
ModuleCollection.

In the code, I want to iterate through the collection so I tried this code:

For Each oMod As IClientModule In m_Modules
...
Next

When it gets to that line of code, it pukes with an "Specified Cast is
Invalid" on the For Each line.

Yet if I change the code to this:

Dim oMod As IClientModule
For x As Integer = 0 To m_Modules.Count - 1
oMod = m_Modules(x)
oMod.InitializePlugin(AppContext)
Next

It works!?!?! What gives? Why would it fail with For Each?

--
Chris

dunawayc[AT]sbcglobal_lunchmeat_[DOT]net

To send me an E-mail, remove the "[", "]", underscores ,lunchmeat, and
replace certain words in my E-Mail address.
 
P

Phil Harvey

Hi Chris,
You could try using an ArrayList instead of a type collection and convert
the array list to a typed array at the last minute.
For example:

For Each oMod As IClientModule In m_Modules.ToArray(GetType(IClientModule))
...
Next

Phil Harvey
 
C

Chris Dunaway

Hi Chris,
You could try using an ArrayList instead of a type collection and convert
the array list to a typed array at the last minute.
For example:

For Each oMod As IClientModule In m_Modules.ToArray(GetType(IClientModule))
...
Next

Phil Harvey

The problem is that on the For Each line, it throws the "Specified Cast Is
Invalid" error. Why does for each do this when a regular for loop does
not?

--
Chris

dunawayc[AT]sbcglobal_lunchmeat_[DOT]net

To send me an E-mail, remove the "[", "]", underscores ,lunchmeat, and
replace certain words in my E-Mail address.
 
I

Imran Koradia

Are you inheriting your collection from an existing one are have you
implemented IEnumerable/IEnumerator? I had a go with the
IEnumerable/IEnumerator implementations and in that case, 'for each' worked
fine even with an interface variable. Looks like the Current() method of the
IEnumerator is returning an object that doesn't implement
IClientModule...seems like the most obvious reason for an invalid cast but
I'm not sure how this would apply in the case where you have inherited from
an exisiting collection. Could you provide a little more detail about your
collection class?


Imran.


Chris Dunaway said:
Hi Chris,
You could try using an ArrayList instead of a type collection and convert
the array list to a typed array at the last minute.
For example:

For Each oMod As IClientModule In m_Modules.ToArray(GetType(IClientModule))
...
Next

Phil Harvey

The problem is that on the For Each line, it throws the "Specified Cast Is
Invalid" error. Why does for each do this when a regular for loop does
not?

--
Chris

dunawayc[AT]sbcglobal_lunchmeat_[DOT]net

To send me an E-mail, remove the "[", "]", underscores ,lunchmeat, and
replace certain words in my E-Mail address.
 
C

Chris Dunaway

Are you inheriting your collection from an existing one are have you
implemented IEnumerable/IEnumerator? I had a go with the
IEnumerable/IEnumerator implementations and in that case, 'for each' worked

I didn't create my collection class from scratch, I inherited from
DictionaryBase and overrode the Add, Insert, etc.

I guess in that case, Im relying on the base class enumerator. You think
that could be causing the problem?

--
Chris

dunawayc[AT]sbcglobal_lunchmeat_[DOT]net

To send me an E-mail, remove the "[", "]", underscores ,lunchmeat, and
replace certain words in my E-Mail address.
 
A

Alexandre Moura

Not sure if I fully understood your scenario, but unless your interface is defined in a single dll that your other dll's then reference and use, instances from
different assemblies (dlls) will be considered different, and casts will fail.
In .Net, a type is identified not only by its name, but also by the assembly it was defined in.

To work, you need:

MainDll
defines IClientModule

dll1
references IClientModule, has class that implements it

dll2
references IClientModule, has another class that implements it

dll3
...


mainexe
references maindll
dynamically loads dll1-dll3, and searches for types that implement IClientModule
code: dim x as IClientModule = assembly1.createinstance("ClassthatimplementsClientModule")


Hope that helps
Alex
--------------------
From: Chris Dunaway <"dunawayc[[at]_lunchmeat_sbcglobal[dot]]net">
Subject: Interface question
User-Agent: 40tude_Dialog/2.0.10.1
MIME-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
Date: Fri, 3 Dec 2004 09:54:45 -0600
Message-ID: <[email protected]>
Newsgroups: microsoft.public.dotnet.languages.vb
NNTP-Posting-Host: 216.143.212.98
Lines: 1
Path: cpmsftngxa10.phx.gbl!TK2MSFTFEED02.phx.gbl!TK2MSFTNGP08.phx.gbl!TK2MSFTNGP11.phx.gbl
Xref: cpmsftngxa10.phx.gbl microsoft.public.dotnet.languages.vb:246691
X-Tomcat-NG: microsoft.public.dotnet.languages.vb

I have created an Interface called IClientModule in a class libarary and
have compiled the library to a .dll.

In my main app, I scan a folder for .dll's and load each one that
implements the interface. For each one that is loaded, it is stored in a
collection object which is an instance of a typed collection class called
ModuleCollection.

In the code, I want to iterate through the collection so I tried this code:

For Each oMod As IClientModule In m_Modules
...
Next

When it gets to that line of code, it pukes with an "Specified Cast is
Invalid" on the For Each line.

Yet if I change the code to this:

Dim oMod As IClientModule
For x As Integer = 0 To m_Modules.Count - 1
oMod = m_Modules(x)
oMod.InitializePlugin(AppContext)
Next

It works!?!?! What gives? Why would it fail with For Each?

--
Chris

dunawayc[AT]sbcglobal_lunchmeat_[DOT]net

To send me an E-mail, remove the "[", "]", underscores ,lunchmeat, and
replace certain words in my E-Mail address.

Sorry I don't take feature request for WinRes: it belongs to the .NET Framework SDK. I'm a consumer of WinRes, just like you...
--------------------
From: Thomas Adams <[email protected]>
Newsgroups: microsoft.public.dotnet.internationalization
Subject: RE: How to launch WinRes in full screen mode by another program?
Date: 29 Sep 2004 19:31:46 GMT
Organization: DFN.CIS Senior Customer
Lines: 17
Message-ID: <[email protected]>
References: <[email protected]> <[email protected]>
X-Trace: news.uni-berlin.de cGk7xWd2iWxkO9HVbF7isQODBzMeOPRUidb0ZHc/H3nGY=
User-Agent: Xnews/06.08.25
X-Converter: MorVer Version 1.0.305
Path: cpmsftngxa06.phx.gbl!TK2MSFTNGXA03.phx.gbl!TK2MSFTNGP08.phx.gbl!newsfeed00.sul.t-online.de!newsfeed01.sul.t-online.de!t-online.de!fu- berlin.de!uni-berlin.de!not-for-mail
Xref: cpmsftngxa06.phx.gbl microsoft.public.dotnet.internationalization:947
X-Tomcat-NG: microsoft.public.dotnet.internationalization

Hi

Your assumption is correct. I did not want to call out its long name
since I didn't know if that could be regarded as breach of NDA. :)

Thanks for the explanation. Do you take feature requests for WinRes?
I'd like to see a "remember last size and location" some day...

~T.

(e-mail address removed) (Xu Yang[MSFT]) wrote:

I'm afraid that LocStudio (when you say LS, I assume you are using LocStudio) does not have the option, and WinRes does not remember its size and
location when it was shut down.
If you are trying to call it in your own application, you can always use ProcessWindowStyle.Maximized when you start the process.

--------------------
From: Thomas Adams <[email protected]>
Newsgroups: microsoft.public.dotnet.internationalization
Subject: How to launch WinRes in full screen mode by another program?
Date: 11 Sep 2004 21:26:17 GMT
Organization: DFN.CIS Senior Customer
Lines: 9
Message-ID: <[email protected]>
X-Trace: news.uni-berlin.de 9sj2ViefNkwlw4tmA89WfA6mie8fmrCfbXqlIJqRehUb0=
User-Agent: Xnews/06.08.25
X-Face: #Rk@TOQ|^!ZG|&z6lA@-CY>/xB[Ei1mG*&S.+A5z;Ng?3OxX[#DVZw!"o!c`S|p:(zsX-EkdZZ(IVnFRTX%!:Sv^L&Gk~s]vJ@Z~%Rm@G]fr*r2P}u5 *&k/-_2+&Qowj6hiJ1b$^JQf:uy9456HIdKq*B`NC##kyO,>7"Ztnav+=71b*"E+DIme;{i&)ii{#6e?i8P,1Xpc[q0}i:Tm];B1
X-Converter: MorVer Version 1.0.305
Path: cpmsftngxa10.phx.gbl!TK2MSFTFEED01.phx.gbl!TK2MSFTNGP08.phx.gbl!newsfeed00.sul.t-online.de!newsfeed01.sul.t-online.de!t-online.de!fu- berlin.de!uni-berlin.de!not-for-mail
Xref: cpmsftngxa10.phx.gbl microsoft.public.dotnet.internationalization:902
X-Tomcat-NG: microsoft.public.dotnet.internationalization

Hi

Let's imagine you're using a translation environment (LS) that's
launching WinRes every now and then. Is it possible to open WinRes in
full screen mode in this case? It's quite annoying that it doesn't
remember if I switch it to full screen mode the next time it is invoked.

thanks,
Thomas
 
D

David

I didn't create my collection class from scratch, I inherited from
DictionaryBase and overrode the Add, Insert, etc. ^^^^^^^^^^^^^^

I guess in that case, Im relying on the base class enumerator. You think
that could be causing the problem?

Why DictionaryBase? Assuming you inherited in a ordinary way...

For Each obj In m_modules

is going to return a DictionaryKey object that contains the key/value
pair, while

m_modules(i)

will return the actual object you inserted with the key of 'i'.

That's why you have this situation. You seem to want a simple indexed
collection here rather than key/value pairs, so I would guess that you
really want CollectionBase rather than DictionaryBase.
 
J

Jay B. Harlow [MVP - Outlook]

Chris,
I didn't create my collection class from scratch, I inherited from
DictionaryBase and overrode the Add, Insert, etc.
Ah! There's the rub.

When you use a For Each on a DictionaryBase you need to use a
DictionaryEntry for the item as it returns both the key & the value.

Change your For Each to be something like:

For Each de As DictionaryEntry In m_Modules
Dim oMod As IClientModule = DirectCast(de.Value, IClientModule)
...
Next

As David, suggests you may want to consider using a CollectionBase instead
of a DictionaryBase. I would also consider using a
System.Collections.Specialized.NameObjectCollectionBase instead of either of
the other two...

Hope this helps
Jay

Chris Dunaway said:
Are you inheriting your collection from an existing one are have you
implemented IEnumerable/IEnumerator? I had a go with the
IEnumerable/IEnumerator implementations and in that case, 'for each'
worked

I didn't create my collection class from scratch, I inherited from
DictionaryBase and overrode the Add, Insert, etc.

I guess in that case, Im relying on the base class enumerator. You think
that could be causing the problem?

--
Chris

dunawayc[AT]sbcglobal_lunchmeat_[DOT]net

To send me an E-mail, remove the "[", "]", underscores ,lunchmeat, and
replace certain words in my E-Mail address.
 
C

Chris Dunaway

On Fri, 3 Dec 2004 09:54:45 -0600, Chris Dunaway wrote:


Thanks, All, for the help.

--
Chris

dunawayc[AT]sbcglobal_lunchmeat_[DOT]net

To send me an E-mail, remove the "[", "]", underscores ,lunchmeat, and
replace certain words in my E-Mail address.
 
C

Chris Dunaway

When you use a For Each on a DictionaryBase you need to use a
DictionaryEntry for the item as it returns both the key & the value.

Thanks, David, Jay, I knew this, I don't know why my brain was not working
in this instance!! I guess it needs a service pack!

--
Chris

dunawayc[AT]sbcglobal_lunchmeat_[DOT]net

To send me an E-mail, remove the "[", "]", underscores ,lunchmeat, and
replace certain words in my E-Mail address.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top