2

I have a situation where I have functionality that I want to use across more than 1 application. In particular, I have a Repository taking the form of a C# class library containing things like a EF .edmx, repository, and UnitOfWork that are generic enough to use across applications.

I'm frustrated that I can't see the picture more clearly because I should understand clearly the differences; and I do to a point. However I think I can't see through to the ramifications of each choice and the overall differences.

I have read this link: How do you share code between projects/solutions in Visual Studio? and it offers some good advice, but both suggestions seem to hold water. I want to understand better the downstream impacts of each and understand which is the proper selection for my need.

I believe with linking files I would create another new Repository project in Application-2, but use the linked files for what comprises that new layer.

I believe with adding the Repository from Application-1 as a reference to Application-2 will work, but I'm not sure what the impact of changing code will be.

I basically need to know which method will yield the correct result for my need to share the repository layer among 1..n applications?

Community
  • 1
  • 1
atconway
  • 20,624
  • 30
  • 159
  • 229

1 Answers1

5

If you have an implementation of Repository/UnitOfWork, which you want to share across multiple standalone projects, you have following options:

  1. Put source *.cs files in some common folder, and add these files as links into each project.

    Pros:

    • All bug fixes / features automatically get into all projects.
    • You can debug your Repository code.
    • Since code is shared as a set of files, each solution can have its own custom data access project, which can extend base shared repository code.


    Cons:

    • Same code duplicated in both compiled projects, and if at some point project1 will start depending on project2, there will be a class name / namespace conflict, which you would have to manually resolve (see comment from Tom Blodget below).
    • Code changes to shared class must be done carefully, not to break existing functionality (for example, removing repository method which is already used in some other project).
    • If shared code is linked into several libraries, it is basically the same as copy-pasting it.


  2. Extract common code into class library, include compiled .dll assembly as a reference into both projects.

    Pros:

    • Prevents unexpected contract changes.
    • Possible to have single version of Repository implementation - registered in GAC
    • Possible to completely hide implementation details (making repository internal/sealed), and expose only interfaces.
    • Class library acts like black box, forcing you to implement a better contract interfaces/API.


    Cons:

    • Potential need to support multiple versions of assembly, for example when project1 needs new features from v2.0 of library, and v2.0 contain breaking changes preventing its usage in project2.


  3. Extract into separate class library and include library as a project reference

    Pros:

    • Same as option 1, except Repository code is incapsulated into one shared library, and deployed as a complete solution. Extending it can lead to breaking changes.


    Cons:

    • Reduced control over changes, as in option 1 - changing source code in library can lead to potential breaking changes in other projects.

But again, it all depends on many factors - what kind of version control you are using, what will be lifecycle of your projects, are there multiple teams developing these projects, how these projects will be deployed and whether or not they will be connected. It all affects the final decision.

Alexander
  • 4,153
  • 1
  • 24
  • 37
  • 1
    Compiling the same class file into multiple assemblies does not create a conflict (or if you prefer, does not create an irresolvable conflict). The classes will be distinct types. It is easy using VS and csc to deal with them--just use [extern aliases](http://msdn.microsoft.com/en-us/library/ms173212(v=vs.80).aspx). The real problem is that they would be distinct types and if you wanted to convert between them you'd have to write type conversion methods. And if they are exposed to COM then COM can't distinguish between them. – Tom Blodget Apr 17 '13 at 21:51
  • Thank you, didn't know it was possible. I have edited my answer. – Alexander Apr 18 '13 at 06:11
  • @Alexander - How about a offshoot of Option #2, which is: "Extract common code into class library, and add this new refactored class library as *an existing project* to project #2". This is as opposed to referencing the .dll. I like the thought of adding the reference to an existing project because I can step through code in both projects. Having the .dll does not allow me to do this (without the help of some tools to decompile and step into). – atconway Apr 18 '13 at 18:30
  • @Alexander - Very nice synopsis, thank you. I am using SVN for version control so merging changes is something we are good with. – atconway Apr 19 '13 at 17:12