Reputation: 33491
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:
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
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
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:
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.
parameter of your method to take iList instead. Then you can use other list types too, as long as they implement iList inside them.
internals of the wrapper object, not the object itself.
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).
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
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
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
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
Reputation: 95482
What you really need to do is to use some sort of source control software such that:
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
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
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