Question

Facts

I've got two VS2010 C# single-project solutions:

  1. Class Library which provides functionality regarding to managing a calendar. Let's call it a Manager. https://www.dropbox.com/s/ldjhtn4yxajss7y/Manager.png
  2. Console Application which would like to use this functionality. I'll refer to it as Client. https://www.dropbox.com/s/i4xiuy598ixereg/Client.png

Goals

Both projects are under development, so it would be perfect if I could comfortably work on both of them in one solution, compiling them both at the same time every modification. That way development is fast and easy, because Find definition works, I can Refactor -> Rename in both projects at once, debugging a problem is more precise.


Ideas

... I came up with, none of which worked as flawlessly as intended, every one of which having its shortcomings.


1. Add existing Manager project into Client solution (as a reference)

My personal dream. It would look like this: dropbox.com/s/od7f2n12vw48xdx/Idea1.png

Goals achieved:

  • Building Client forces Manager to be build from the latest code as well
  • Can develop both projects in one solution

Goals not achieved:

  •  

Perfect! But...

Unexpected problems:

  • Visual Studio forces me to reference ALL libraries used in Manager, along with its app.config file for binding redirects. This creates a mess, because in both projects there is copied list of assemblies in References, which needs to be manually maintained - and even if I used NuGet automation, it's still too much redundancy; copying everything twice is not what I expect a Class Library to behave
    dropbox.com/s/xvrl639f5z9sw54/Idea1Problem.png

That led me to other workaround-ideas:


2. Rewrite Manager Class Library to use only REST HTTP communication

Goals achieved:

  • Same as Idea 1, which is good
  • Only one dependency - the Manager assembly, which is even better

Cons:

  • No sense rewriting an already complex, full-blown CalendarService class which is already provided by Google, is there?
  • Development will take lots and lots more time

Foreseeable problems:

  • I have a hunch I would end up with more than one required dependency in the Client project anyways
  • In that case I should have sticked with Idea 1, and any time spent on this idea would be totally wasted

3. Demote Manager to a Console Application. Keep it and Client separate and independent

Manager would be a daemon which awaits commands while active, executes them and stays open until exit is requested, much like cmd in Windows. A Mediator/*Translator* man-in-the-middle project would then be needed to connect Client with Manager, which would provide a class responsible for:

  • Starting and maintaining the Manager application
  • Giving Client the possibility to call methods like Mediator.InsertEvent(Description,StartDate,Duration) in Client's source code
  • Translating those calls into Manager commands, e.g. ManagerProcess.WriteLine("insert description start duration")
  • Parsing its result and communicating it to Client

Goals achieved:

  • Dependency hell avoided = main enemy conquered
  • Client works as intended

But...

Goals not achieved:

  • Projects not connected with one solution with all of shortcomings resulting from that

Cons:

  • Need to maintain a third project serving as an intercommunication layer
  • Increased time of development, but probably less so than while going for Idea 2
  • If Client becomes a daemon itself during the development, there will be two background apps running, while one should be easily enough to get the job done

4. Go one step further and make a Windows Service out of Mediator

Goals achieved:

  • Same as Idea 3
  • Not sure about that, but Mediator class would not be needed - calls could probably be made straight to the service

Goals not achieved:

  • Projects not connected with one solution with all of shortcomings resulting from that

Cons:

  • Two words: Need. Admin. Rights. Well, three words: Would. Be. An. Overkill. For. As. Simple. App. As. This. To. Require. Admin. Rights.
  • If Client becomes a daemon itself during the development, there will be two background apps running, while one should be easily enough to get the job done

5. Abandon hopes for in-memory interactions and communicate Client with Manager via physical iCalendar files

Client creates an .ics file with event to be inserted, starts Manager with the .ics's filepath as argument, Manager inserts the event

Goals achieved:

  • ... Have a Client project which can put something into a Calendar?

Goals not achieved:

  • Projects not connected with one solution with all of shortcomings resulting from that

Cons:

  • Interaction by hard disk. Have mercy...
  • Manager would be logging-in every time it was called to create or update a Calendar event

An idea nevertheless.


What I need from you

Either:

  • A guidance of how to deal with the problem in Idea 1
  • Pointing me which of the remaining Ideas would be the most reasonable to go with (or how to improve them)
  • Another idea if those above don't just cut it and you know a better way

Sorry

For making this question a lecture, I really visioned it to be explainable in five sentences. Failed at that ;)

Was it helpful?

Solution 2

It looks like you are trying to develop a class library and simultaneously develop an application that is dependent on that class library.

My recommendation would be to try this:

  1. Develop the application first, while making the code that you intend to include in your class library as reusable as possible.

  2. Once you have you have finished developing the classes/ interfaces that you intend to include in your class library, separate that code out into a separate library which your application references.

For the sake of simplicity, I'm suggesting this modified approach as apposed to implementing a third assembly which could implement a wrapper object for your references.

Check out Jeff Atwoods post on The Rule of Three to get a sense for what I mean.

The type of reusable code you're looking to develop in your library will be an evolving process that will involve much more thought and rework than that of your application. That doesn't mean that its a bad idea to begin said code as modular components inside your existing application.

OTHER TIPS

The reason you need to share assemblies is that you have shared logic. What I would do is introduce a third assembly/project, called Core or something similar, and centralize/unify your shared logic there... Make Core a wrapper around the references and expose only your methods. Then use the client and manager to reference that project and call those methods.

Instead of:

client  --> tons of references
manager --> tons of references

You get:

core    --> tons of references
client  --> core
manager --> core
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top