Adding new classes without recompiling old code ?

  • Thread starter Thread starter friendhouston
  • Start date Start date
F

friendhouston

Hi,

Have a requirement where new items may be added later to an existing
list of items. These new items may have new features but will need to
contain minimum basic features like description and price. These items
should be added to the existing code without the code being needed to
be recompiled or making minimum changes to the existing code i.e. it
should be OCP compliant. Not sure how to go about this . The only
things which come to my mind are that each new item class should derive
from an IItem interface and that each new class could be placed in a
seperate assembly. Is there some way to use reflection or any other
feature to accomplish this ?

thanks in advance.
 
You could use reflection, but it's not the right way to go on this.

You should do what you said, create an interface, or a base class which
you derive from which exposes the properties common to all of the classes.
Then, have your list work with that base class/interface.

Hope this helps.
 
Nicholas said:
You could use reflection, but it's not the right way to go on this.

You should do what you said, create an interface, or a base class which
you derive from which exposes the properties common to all of the classes.
Then, have your list work with that base class/interface.

Hope this helps.

Yes .. though wondering how to actually go about compiling the new
class without recompilng the existing code and how to add an object
from this class to the list of items.

thanks.
 
Nicholas said:
What is the big deal about recompiling the existing code?

Ok.. trying to keep minimal changes to the existing code .. so maybe
recompiling is okay .. but still keeping modifications to existing code
minimal ..

thanks.
 
Basically you would go through and create a shared .dll with your abstract
contract (consider it a "public" dll) ..

as an example .. in my public dll I have an interface IFoo
public interface IFoo {
public void Bar();
}

now in my code I reference the public interface ...

When you want to create your own implementation .. you create your own .dll
.... referencing the public dll and write your own class implementing IFoo.

public class YourFoo : IFoo {
public void Bar() {
Console.WriteLine("YourFoo::Bar()");
}
}

You compile your .dll and place it in my bin folder.

My application simply needs some way of dynamically loading items into its
space, a very common method of doing this is with the factory pattern. Here
is a naive implementation ..

public class FooFactory {
public static IFoo GetFoo(string _AssemblyName, string _TypeName) {
Assembly a = Assembly.LoadFrom(_AssemblyName) ;
return a.CreateInstance(_TypeName) as IFoo;
}
}

So now, we can given an assembly name and a type name dynamically load items
into our process ... now its just a matter of maintaining those. Another
alternative is to use attributes to allow us to discover the types in the
assembly, avoids having to define th assemblyname/typename as we can instead
assume that anything with a FooPlugin attribute is something that we are
interested in.

Hope this helps a bit,

Greg Young
MVP - C#
 
I have several examples of the "Factory Design Pattern" at my blog:

http://spaces.msn.com/sholliday/ 12/1/2005 entry

The one you're interested in is the reflection method.



Take GREAT care in designing your Interface or Abstract base class.... as
this is the key to keeping the recompile to a minimum.


Please leave a comment if you find it useful.
 
Greg said:
Basically you would go through and create a shared .dll with your abstract
contract (consider it a "public" dll) ..

as an example .. in my public dll I have an interface IFoo
public interface IFoo {
public void Bar();
}

now in my code I reference the public interface ...

When you want to create your own implementation .. you create your own .dll
... referencing the public dll and write your own class implementing IFoo.

public class YourFoo : IFoo {
public void Bar() {
Console.WriteLine("YourFoo::Bar()");
}
}

You compile your .dll and place it in my bin folder.

My application simply needs some way of dynamically loading items into its
space, a very common method of doing this is with the factory pattern. Here
is a naive implementation ..

public class FooFactory {
public static IFoo GetFoo(string _AssemblyName, string _TypeName) {
Assembly a = Assembly.LoadFrom(_AssemblyName) ;
return a.CreateInstance(_TypeName) as IFoo;
}
}

So now, we can given an assembly name and a type name dynamically load items
into our process ... now its just a matter of maintaining those. Another
alternative is to use attributes to allow us to discover the types in the
assembly, avoids having to define th assemblyname/typename as we can instead
assume that anything with a FooPlugin attribute is something that we are
interested in.

Hope this helps a bit,

Yes it does, in a big way. Just one more question , is there a way to
discover all the assembly names in the bin folder .

thanks.
 
Yes .. Directory.GetFiles will give you all of the file names in the
directory.

Also if you poke around you can find numerous things doing just this as
plugin libraries. I'm sure a google on "C# plugin library" will bring up a
good deal of them.

Cheers,

Greg Young
MVP - C#
 
Hey greg ,

thanks a ton :)

Greg said:
Yes .. Directory.GetFiles will give you all of the file names in the
directory.

Also if you poke around you can find numerous things doing just this as
plugin libraries. I'm sure a google on "C# plugin library" will bring up a
good deal of them.

Cheers,

Greg Young
MVP - C#
 

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

Back
Top