Casting "object" to "real/useful" Type
Casting "object" to "real/useful" Type
am 22.04.2008 19:12:19 von Peter Schwartz
I'm working on a plug-in architecture whereby my application dynamically
loads assemblies based on runtime conditions.
I plan to use Activator.CreateInstance to instantiate objects from the
dynamically loaded assemblies. Activator.CreateInstance of course returns
the created type as 'object'. I therefore need to cast that returned
'object' to the real type that I want (e.g., MyDal, and not 'object' - where
MyDal is a class).
My question (yes, I think there ARE dumb questions - and this might be
one! - but here goes):
Why does the application that calls Activator.CreateInstance need to know
_at compile time_ the specific Type to convert the 'object' to? It makes
perfect sense to me that the application would have to _somehow_ know ahead
of time the definition of the class type named MyDal in order to cast
'object' variables to MyDal.
I am just hung up on the fact that that knowledge has to come [apparently to
me] via a static reference (project reference). Doesn't Reflection provide
us with a way to accomplish this without a static reference?
Why can't we use Reflection to equip an application with the ability to cast
an 'object' to it's "useful type" (e.g., MyDal) -- so that the application
that is calling Activator.CreateInstance can itself, at compile time, _not_
know anything about the MyDal type (a class), and instead acquire that
knowledge at runtime. Ideally, the application could somehow cast 'object'
types to "real types" without having any compile-time knowledge of the "real
type."
What am I missing?
Thanks in advance.
Re: Casting "object" to "real/useful" Type
am 22.04.2008 19:24:38 von George Ter-Saakov
You need to read up on "Interfaces"
Example:
interface ISampleInterface
{
void SampleMethod();
}
class ImplementationClass : ISampleInterface
{
void ISampleInterface.SampleMethod()
{
}
static void Main()
{
ISampleInterface obj = new ImplementationClass();
obj.SampleMethod();
}
}
so let say you have bunch of dynamically loaded objects... And they all
support interface ISampleInterface.
So application casts your object to ISampleInterface and calls it's methods.
Thus application does not need to know ahead of time of the class
ImplementationClass. The only requirement is that
it knows about ISampleInterface.
So the usual practice to compile interfaces into separate DLL and your
application only reference that DLL (to know about interace) And your
dynamicly loaded object will need to reference the same DLL to be able to
implement that interface.
George.
"Robert" wrote in message
news:%23ozXNwJpIHA.3940@TK2MSFTNGP03.phx.gbl...
> I'm working on a plug-in architecture whereby my application dynamically
> loads assemblies based on runtime conditions.
>
> I plan to use Activator.CreateInstance to instantiate objects from the
> dynamically loaded assemblies. Activator.CreateInstance of course returns
> the created type as 'object'. I therefore need to cast that returned
> 'object' to the real type that I want (e.g., MyDal, and not 'object' -
> where MyDal is a class).
>
> My question (yes, I think there ARE dumb questions - and this might be
> one! - but here goes):
>
> Why does the application that calls Activator.CreateInstance need to know
> _at compile time_ the specific Type to convert the 'object' to? It makes
> perfect sense to me that the application would have to _somehow_ know
> ahead of time the definition of the class type named MyDal in order to
> cast 'object' variables to MyDal.
>
> I am just hung up on the fact that that knowledge has to come [apparently
> to me] via a static reference (project reference). Doesn't Reflection
> provide us with a way to accomplish this without a static reference?
>
> Why can't we use Reflection to equip an application with the ability to
> cast an 'object' to it's "useful type" (e.g., MyDal) -- so that the
> application that is calling Activator.CreateInstance can itself, at
> compile time, _not_ know anything about the MyDal type (a class), and
> instead acquire that knowledge at runtime. Ideally, the application could
> somehow cast 'object' types to "real types" without having any
> compile-time knowledge of the "real type."
>
> What am I missing?
>
> Thanks in advance.
>
>
>
>
>
Re: Casting "object" to "real/useful" Type
am 22.04.2008 19:34:40 von sloan
To follow up on this post:
http://sholliday.spaces.live.com/Blog/cns!A68482B9628A842A!1 26.entry
Get that downloadable code, and look at the "reflection based simple factory
pattern".
...
"George Ter-Saakov" wrote in message
news:ehFf$2JpIHA.4884@TK2MSFTNGP06.phx.gbl...
> You need to read up on "Interfaces"
>
> Example:
> interface ISampleInterface
> {
> void SampleMethod();
> }
>
> class ImplementationClass : ISampleInterface
> {
> void ISampleInterface.SampleMethod()
> {
> }
>
> static void Main()
> {
> ISampleInterface obj = new ImplementationClass();
> obj.SampleMethod();
> }
> }
>
> so let say you have bunch of dynamically loaded objects... And they all
> support interface ISampleInterface.
> So application casts your object to ISampleInterface and calls it's
> methods.
>
> Thus application does not need to know ahead of time of the class
> ImplementationClass. The only requirement is that
> it knows about ISampleInterface.
> So the usual practice to compile interfaces into separate DLL and your
> application only reference that DLL (to know about interace) And your
> dynamicly loaded object will need to reference the same DLL to be able to
> implement that interface.
>
> George.
>
>
> "Robert" wrote in message
> news:%23ozXNwJpIHA.3940@TK2MSFTNGP03.phx.gbl...
>> I'm working on a plug-in architecture whereby my application dynamically
>> loads assemblies based on runtime conditions.
>>
>> I plan to use Activator.CreateInstance to instantiate objects from the
>> dynamically loaded assemblies. Activator.CreateInstance of course returns
>> the created type as 'object'. I therefore need to cast that returned
>> 'object' to the real type that I want (e.g., MyDal, and not 'object' -
>> where MyDal is a class).
>>
>> My question (yes, I think there ARE dumb questions - and this might be
>> one! - but here goes):
>>
>> Why does the application that calls Activator.CreateInstance need to know
>> _at compile time_ the specific Type to convert the 'object' to? It makes
>> perfect sense to me that the application would have to _somehow_ know
>> ahead of time the definition of the class type named MyDal in order to
>> cast 'object' variables to MyDal.
>>
>> I am just hung up on the fact that that knowledge has to come [apparently
>> to me] via a static reference (project reference). Doesn't Reflection
>> provide us with a way to accomplish this without a static reference?
>>
>> Why can't we use Reflection to equip an application with the ability to
>> cast an 'object' to it's "useful type" (e.g., MyDal) -- so that the
>> application that is calling Activator.CreateInstance can itself, at
>> compile time, _not_ know anything about the MyDal type (a class), and
>> instead acquire that knowledge at runtime. Ideally, the application could
>> somehow cast 'object' types to "real types" without having any
>> compile-time knowledge of the "real type."
>>
>> What am I missing?
>>
>> Thanks in advance.
>>
>>
>>
>>
>>
>
>
Re: Casting "object" to "real/useful" Type
am 22.04.2008 20:26:16 von Peter Schwartz
Thanks George, I really am grateful for attempts to be helpful, but this
really doesn't answer the question in my OP.
What I am looking for is an explanation of WHY things are this way (I was
not looking for a work-around).
Again, I am appreciative of the feedback. I will note, that even though I
can use Interfaces, the calling application and the dynamically loaded
assembly both need compile-time refrences to the assembly that contains the
interfaces (as you accurately pointed out). This does not answer the core
question I have about the need to have compile-time references.
Again, the question is all about an explanation of WHY we must have
compile-time references... and why Reflection cannot get us around that
apparent requrement.
-Robert
Re: Casting "object" to "real/useful" Type
am 22.04.2008 20:36:03 von skeet
Robert wrote:
> Thanks George, I really am grateful for attempts to be helpful, but this
> really doesn't answer the question in my OP.
>
> What I am looking for is an explanation of WHY things are this way (I was
> not looking for a work-around).
>
> Again, I am appreciative of the feedback. I will note, that even though I
> can use Interfaces, the calling application and the dynamically loaded
> assembly both need compile-time refrences to the assembly that contains the
> interfaces (as you accurately pointed out). This does not answer the core
> question I have about the need to have compile-time references.
>
> Again, the question is all about an explanation of WHY we must have
> compile-time references... and why Reflection cannot get us around that
> apparent requrement.
If you're willing to make *all* the calls via reflection, then you can
indeed work completely without any other references.
--
Jon Skeet -
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
World class .NET training in the UK: http://iterativetraining.co.uk
Re: Casting "object" to "real/useful" Type
am 22.04.2008 20:37:44 von sloan
You must have a compile time reference TO THE INTERFACE.
This is why the interface library should be stand alone...and you can put
the concrete's anywhere you'd like.
If you follow my example, it will show you ( I believe ) a non compile time
reference.
.....
as my example shows:
assemblyName="GranadaCoder.Applications.FactoryPatternExampl es.ConcreteObjectsOutsideBaseAssembly"
className="GranadaCoder.Applications.FactoryPatternExamples. ConcreteObjectsOutsideBaseAssembly.ConcreteRateQuoters.UPSRa teQuoter"
ShippingCompanyHomeState="NC"/>
I have a "Quoter" that isn't referenced. Or at least, doesn't need to be
referenced.
...
DotNet has to know ~at least~ about the interface if you want it to return
something other than object.
"Robert" wrote in message
news:OojEiZKpIHA.2256@TK2MSFTNGP05.phx.gbl...
> Thanks George, I really am grateful for attempts to be helpful, but this
> really doesn't answer the question in my OP.
>
> What I am looking for is an explanation of WHY things are this way (I was
> not looking for a work-around).
>
> Again, I am appreciative of the feedback. I will note, that even though I
> can use Interfaces, the calling application and the dynamically loaded
> assembly both need compile-time refrences to the assembly that contains
> the interfaces (as you accurately pointed out). This does not answer the
> core question I have about the need to have compile-time references.
>
> Again, the question is all about an explanation of WHY we must have
> compile-time references... and why Reflection cannot get us around that
> apparent requrement.
>
> -Robert
>
>
>
>
Re: Casting "object" to "real/useful" Type
am 22.04.2008 21:18:04 von ignacio.machin
On Apr 22, 2:26=A0pm, "Robert" wrote:
> Thanks George, I really am grateful for attempts to be helpful, but this
> really doesn't answer the question in my OP.
>
> What I am looking for is an explanation of WHY things are this way (I was
> not looking for a work-around).
>
> Again, I am appreciative of the feedback. I will note, that even though I
> can use Interfaces, the calling application and the dynamically loaded
> assembly both need compile-time refrences to the assembly that contains th=
e
> interfaces (as you accurately pointed out). This does not answer the core
> question I have about the need to have compile-time references.
>
> Again, the question is all about an explanation of WHY we must have
> compile-time references... and why Reflection cannot get us around that
> apparent requrement.
>
> -Robert
Hi,
You do not need add a refeence at compile time if you load all your
dlls using Assembly.Load() and call members using reflection.
It's a slow and convoluted way of doing it, but you can do it.
Re: Casting "object" to "real/useful" Type
am 22.04.2008 21:20:31 von ignacio.machin
> Why can't we use Reflection to equip an application with the ability to cast
> an 'object' to it's "useful type" (e.g., MyDal) -- so that the application
> that is calling Activator.CreateInstance can itself, at compile time, _not_
> know anything about the MyDal type (a class), and instead acquire that
> knowledge at runtime. Ideally, the application could somehow cast 'object'
> types to "real types" without having any compile-time knowledge of the "real
> type."
>
> What am I missing?
The difference between compile & runtime. CreateInstance works at
runtime, you can pass ANY string to it (even an incorrect one like
"123123123123") and it will compile
Only at runtime you will get the error.
And honestly, you HAVE to know something about your Class. otherwise,
how do you know which method to call?
Re: Casting "object" to "real/useful" Type
am 22.04.2008 21:59:53 von George Ter-Saakov
I think I understood now...
What you want is called late binding.
You can do that. I heard it's easier done in VB.NET than in C#. Google it.
The only thing I do not understand is what you are trying to do. To do
something meaningful you need to know what kind of object you working with.
Even if you do not want to do "early binding" via interface you need to know
what this object doing....
Obviously, in order to call the object, you need to know what methods it
supports... Let say it has "RunMe" method.. Are you just going to call it?
My guess you expected this object to have that method... But then why not to
have it in interface and use early binding?
The interface
George.
"Robert" wrote in message
news:OojEiZKpIHA.2256@TK2MSFTNGP05.phx.gbl...
> Thanks George, I really am grateful for attempts to be helpful, but this
> really doesn't answer the question in my OP.
>
> What I am looking for is an explanation of WHY things are this way (I was
> not looking for a work-around).
>
> Again, I am appreciative of the feedback. I will note, that even though I
> can use Interfaces, the calling application and the dynamically loaded
> assembly both need compile-time refrences to the assembly that contains
> the interfaces (as you accurately pointed out). This does not answer the
> core question I have about the need to have compile-time references.
>
> Again, the question is all about an explanation of WHY we must have
> compile-time references... and why Reflection cannot get us around that
> apparent requrement.
>
> -Robert
>
>
>
>
Re: Casting "object" to "real/useful" Type
am 22.04.2008 22:01:01 von brucebarker
its because the .net runtime is strongly typed. to call a method or access a
property, the type of the object must be known at compile time. the major
workaround is as suggested using interfaces.
other languages (javascript, ruby, python, object-c, smalltalk, etc) support
dynamic binding, which allows your code to just call the method.
even java (which is also strongly typed) supports runtime re-compiles so
that plugins and remoting will work the way you expect. this feature was left
out of .net for various performance reasons.
..net now has a dlr (dynamic language runtime) that supports this behavior,
but you need to use a dlr language like IronPython, IronRuby or managed
JScript.
-- bruce (sqlwork.com)
"Robert" wrote:
> Thanks George, I really am grateful for attempts to be helpful, but this
> really doesn't answer the question in my OP.
>
> What I am looking for is an explanation of WHY things are this way (I was
> not looking for a work-around).
>
> Again, I am appreciative of the feedback. I will note, that even though I
> can use Interfaces, the calling application and the dynamically loaded
> assembly both need compile-time refrences to the assembly that contains the
> interfaces (as you accurately pointed out). This does not answer the core
> question I have about the need to have compile-time references.
>
> Again, the question is all about an explanation of WHY we must have
> compile-time references... and why Reflection cannot get us around that
> apparent requrement.
>
> -Robert
>
>
>
>
>
Re: Casting "object" to "real/useful" Type
am 22.04.2008 22:38:50 von Peter Schwartz
Thank you Bruce for answering my specific question. I have a Quick followup
question:
Is it true then [given your response] that I _cannot_ do step 3 of the
following sequence from my C# application:
1. load an .NET assembly via Reflection - where my application has
absolutely no compile-time knowledge of the assembly or the types within
that assembly (i.e., no project reference to the assembly). This step, by
itself, is obviously easy to do using Reflection.
2. use Reflection to identify the types within that assembly. This step, by
itself, is obviously easy to do using Reflection.
3. instantiate a class of a specific type from within that assembly. This
step, given steps 1 and 2 above cannot happen, and for the reasons you
gave - yes?
For example, MyApp is a C# app that loads the Some3rdParty assembly, which
is a .NET assembly that contains a class named Frapper. Apparently because
the .NET runtime is strongly typed, MyApp _cannot_ create a Frapper instance
_unless_ MyApp also has a compile-time reference to the Some3rdParty
assembly. Is this correct, and for the reasons you stated?
I'm asking this because I want to verify that I understand your response.
Please note that I'm not asking about the merits of doing this, and I'm not
attempting to solve some problem "the hard way". My interest is mostly
academic... just wanting to understand things more clearly, and particularly
to find out if my understanding is incorrect. FWIW, I have already done a
couple of plug-in apps that go with the interface-based recommendations
others have made elsewhere in this thread. I'm clear on that... I just want
to know why, and I think I do now - provided that I understand your
response.
Thanks.
"bruce barker" wrote in message
news:3C80B51D-1979-495F-8C46-EF9F62FDA234@microsoft.com...
> its because the .net runtime is strongly typed. to call a method or access
> a
> property, the type of the object must be known at compile time. the major
> workaround is as suggested using interfaces.
>
> other languages (javascript, ruby, python, object-c, smalltalk, etc)
> support
> dynamic binding, which allows your code to just call the method.
>
> even java (which is also strongly typed) supports runtime re-compiles so
> that plugins and remoting will work the way you expect. this feature was
> left
> out of .net for various performance reasons.
>
> .net now has a dlr (dynamic language runtime) that supports this behavior,
> but you need to use a dlr language like IronPython, IronRuby or managed
> JScript.
>
>
> -- bruce (sqlwork.com)
>
>
> "Robert" wrote:
>
>> Thanks George, I really am grateful for attempts to be helpful, but this
>> really doesn't answer the question in my OP.
>>
>> What I am looking for is an explanation of WHY things are this way (I was
>> not looking for a work-around).
>>
>> Again, I am appreciative of the feedback. I will note, that even though I
>> can use Interfaces, the calling application and the dynamically loaded
>> assembly both need compile-time refrences to the assembly that contains
>> the
>> interfaces (as you accurately pointed out). This does not answer the core
>> question I have about the need to have compile-time references.
>>
>> Again, the question is all about an explanation of WHY we must have
>> compile-time references... and why Reflection cannot get us around that
>> apparent requrement.
>>
>> -Robert
>>
>>
>>
>>
>>
>
Re: Casting "object" to "real/useful" Type
am 23.04.2008 13:35:16 von Hans Kesting
Robert expressed precisely :
> I'm working on a plug-in architecture whereby my application dynamically
> loads assemblies based on runtime conditions.
>
> I plan to use Activator.CreateInstance to instantiate objects from the
> dynamically loaded assemblies. Activator.CreateInstance of course returns the
> created type as 'object'. I therefore need to cast that returned 'object' to
> the real type that I want (e.g., MyDal, and not 'object' - where MyDal is a
> class).
>
> My question (yes, I think there ARE dumb questions - and this might be one! -
> but here goes):
>
> Why does the application that calls Activator.CreateInstance need to know _at
> compile time_ the specific Type to convert the 'object' to? It makes perfect
> sense to me that the application would have to _somehow_ know ahead of time
> the definition of the class type named MyDal in order to cast 'object'
> variables to MyDal.
>
> I am just hung up on the fact that that knowledge has to come [apparently to
> me] via a static reference (project reference). Doesn't Reflection provide us
> with a way to accomplish this without a static reference?
>
> Why can't we use Reflection to equip an application with the ability to cast
> an 'object' to it's "useful type" (e.g., MyDal) -- so that the application
> that is calling Activator.CreateInstance can itself, at compile time, _not_
> know anything about the MyDal type (a class), and instead acquire that
> knowledge at runtime. Ideally, the application could somehow cast 'object'
> types to "real types" without having any compile-time knowledge of the "real
> type."
>
> What am I missing?
>
> Thanks in advance.
Activator.CreateInstance *does* create the specific Type it was
requested to do, only it returns it cast to an 'object'. It doesn't
matter that the assembly that contains that type was not available
during compilation (but it needs to be available during runtime).
BUT if you want to call some methods or access some properties of that
object, then the compiler will want to know something about that
'object'. That is why you need to cast it to something. Usually this
means casting to some baseclass or interface that contains those
methods/properties you want to use, instead of the specific "real"
type.
Hans Kesting