Mark Struzinski
Mark Struzinski

Reputation: 33491

Best Way to Reuse Code When Using Visual Studio?

I've tried two different methods of reusing code. I have a solution full of just class library projects with generic code that I reuse in almost every project I work on. When I get to work on a new project, I will reuse code from this code library in one of two ways:

  1. I have tried bringing the projects I need from this code library into my project.
  2. I have also tried compiling down to a .dll and referencing the .dll from a folder in the root of my current solution.

While the second method seems easier and lighter to implement, I always find myself making small tweaks to the original code to fit it into the context of my current project.

I know this is a bit of a vague question, but has anyone had success with other methods of reusing class libraries on new solutions?

Upvotes: 5

Views: 6260

Answers (8)

Rob Cooper
Rob Cooper

Reputation: 28867

In short, what you are doing is right, you want to move the common code into a class library (DLL) and then reference that in any projects that require its logic.

Where you are going wrong is that you are not maintaining it. If you need to make little "tweaks", subclass your existing code and extend it, dont change it.. If there are major changes needed, then re-think the design.

Upvotes: 8

gouderadrian
gouderadrian

Reputation: 431

The idea is good - put your code in a common dll and refer to it. We use this method extensively and it works. Obviously some projects will get out-of-sync eventually so the way we do it is this:

  • Be least specific, if you can use generic types then do so. For example, if you want a function that handles nulls or nothing values and

returns something, implementing NullConvert(o as object, subst as object) as object is better than NullConvert(o as object, String) as

String. Then you can add other types leaving the signature intact. BUT, if a type is not handled, be specific within the method and raise exceptions for unhandled types - don't leave it to chance that it works. In the example above, examine the type of the return value and check if your implementation handles that type.

  • Group functions by type in your namespace; MyGeneric.DateFns, MyGeneric.StringFns, MyGeneric.Comms, etc.

  • Don't change functionality once a class or method is used and it might not be safe to do so. Mark them as Deprecated and include comments to indicate where a newer / better class has been placed.

  • You might consider two or more libraries, for example, Common Methods and Classes in a base library, and domain specific classes and

functions that use common methods (from the base library) in another library (at a higher level). That way, the base library will not need to change all the time.

  • Consider the use of "Implementations" instead of classes. If you have a function that processes an ArrayList for example, set the

parameter of your method to take iList instead. Then you can use other list types too, as long as they implement iList inside them.

  • Avoid introducing specifics, for example, an explicit driver (Oracle 8.x). Wrap that up in something else so if it changes, change the

internals of the wrapper object, not the object itself.

  • Learn how to use reflection. Let's say you need a function to get Distinct values from an array of objects. You may use reflection and

then pass the property name/s you need to get distinct for; GetDistinct(MyList as iList, "Name") as List(of String). Your code may look at

the parameter called 'Name' through reflection (there's a small performance penalty involved).

  • Learn how to write Extensions (Component Model). For example if you are writing a function to always return a sepcifically formatted

date, turn the function into an extension function. Name wisely, if your company's name is ABC then use ABCDateFormat for example, to distinguish between your and MS functions for example.

There's too much one should do to be listed here. Your's is a step in the right direction.

Upvotes: 0

Anthony Mastrean
Anthony Mastrean

Reputation: 22404

Some really good re-usable code is in Ayende Rahien's Rhino Tools. Take a peek at not only how he implements various common code, but how it is organized.

Upvotes: 0

Dale Ragan
Dale Ragan

Reputation: 18270

I have done it both ways that you mentioned. I like the second, but like you said, it is a little tedious for when you make updates to that library.

Another way that I have used, is choosing a central location to keep your libraries. Then add a registry key with a string value to point to that directory. When adding a reference, all your libraries will show up under the .net tab, just like if the libraries were in the GAC. Then you can make a post build command to build the library to that central location.

Here's the registry key, change CompanyName and the directory:

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\AssemblyFolders\ComapnyName]
@="C:\\CentralLocation"

Upvotes: 1

Chris Marasti-Georg
Chris Marasti-Georg

Reputation: 34670

@Outlaw
If you need to copy code and make application-specific changes, then that code isn't generic. it should be refactored so that the common functionality stays in the common library, and the application specific functionality should be added to a subclass in that application's codebase.

Using version control with a branch for each app-specific version can help with integration problems - make your changes in the branch, then test them with your other applications before merging them back to trunk. There are several questions on this site about good free online source control hosts if you don't want to set up your own.

Upvotes: 0

Jon Limjap
Jon Limjap

Reputation: 95482

What you really need to do is to use some sort of source control software such that:

  • Any change that you do in one project will reflect across all projects without loss of referential integrity
  • You may have the option to keep more than one version of the library you have and reference a specific version instead of pulling hairs figuring out which version is used by which project

Just make sure that you have unit tests in hand to make sure that your previous projects are unaffected or only minorly affected by any changes you make on your library.

Goodluck!

Upvotes: 0

Tim Frey
Tim Frey

Reputation: 9941

I don't use Visual Studio or .NET, but it think this problem is common enough amongst ALL programmers so I guess I'll take a crack at it.

We've run into problems just like this when we try to extract common code into a separate library. It might be OK at first, but eventually 1 client is going to need some new functionality and require a change to the library. Invariably this leads to problems with some of the other clients, creating a huge mess. Unless you've got a good way to version your library file, this is a tough problem to solve.

In the end, you might be better off just copying-and-pasting the source files into your new project. Yes, this violates the DRY (Don't Repeat Yourself) principle, but you avoid a lot of problems related to the dependencies a common library creates.

Upvotes: 0

Daniel Jennings
Daniel Jennings

Reputation: 6480

I like to write all of my generic classes as just that: generics. I keep them as application independent as possible, and try to keep them even type unaware. If I make a fancy Tree class, I'll use generics to create it as Tree<T> so that I can use any type I want with the class. If I need to use the Tree to hold GameCharacter objects, I can instantiate Tree<GameCharacter> but if I'm writing a business application I can use it as Tree<Spreadsheet>.

If you find yourself changing your Reuse Libary to match your projects, try making them less specific and instead deriving from your Library base classes in your actual projects. Put all of the common logic in the library classes, and for the application specific parts, create a derived class and implement their logic in that derived class.

As far as solution organization goes, I keep the Reuse Library as a separate project in a common folder and include the project in any solution that I create, which lets me reference easily into it, but also make any changes from any of my applications' solutions.

Upvotes: 0

Related Questions