views:

51

answers:

1

Hi,

I am trying to integrate TFS 2010 with DotSvn. I need to fool Svn into thinking I have checked into it when I make a checkin into TFS. So I need to make a windows service which executes the main method every 5 minutes, get all the checkins commited into TFS, and then make checkins into DotSvn.

The typical C# approach would be to write a windows service which references both the dlls for TFS and DotSvn. I can imagine this will create a high coupling between the TFS and SVN parts of the integration.

How better could I do this? How could web services help?

Thanks

+3  A: 

Creating web services will not automatically decouple technologies, nor will it eliminate the need to reference the assemblies and type libraries for TFS and SVN, unless you choose to write your own wrappers. Nor does simply referencing those files necessarily create coupling. Putting up a web service to share data with partners or clients is usually pretty simple; creating an architecture around web services is a somewhat more involved topic.

To answer the question of "how could web services help", I'm not sure that they will help you here, to be perfectly honest. Common use cases for web services are:

  • Distributed systems/applications;
  • Public-facing APIs (i.e. PayPal, flickr, twitter);
  • Creating a rich standalone "business tier" for a large-scale project;
  • Complex custom security rules;
  • Interoperability over platforms (Java, JavaScript, C++, Delphi, etc.)
  • Providing abstractions over legacy or unstable systems for the purpose of a smooth transition or concurrent production.

...among other things, but the common theme is that they most often tend to be used to solve complex problems or implement complex systems. There are some exceptions, like ADO.NET Data Services, but I'm going to hand-wave those away here so as to avoid further complicating the issue.

What you have is - in relative terms - a fairly simple problem, you have only a single task to perform and only two systems involved, both of which are fairly well-known and well-documented, neither of which are all that likely to change in any significant way. So the benefit of web services here is hard to prove.

A web service can help you provide a common abstraction over the VCS, absolutely. But so can a well-designed set of interfaces and classes libraries held in a small library. In the latter version, you would have an architecture like this:

Sync Application
       |
       +-----> VcsFactory
       |           |
       |           |
    Checkins <==== + ----> ICheckinRepository Source (TFS)
       |           |
    Checkins ====> | ----> ICheckinRepository Destination (SVN)

In other words, you design this with the idea of a generic ICheckinRepository that can give you Checkins (a model class you create), and you use a factory to create two of these, the source (an instance of something like TfsCheckinRepository) and the destination (SvnCheckinRepository), both of which wrap their respective DLLs and implement the generic ICheckinRepository.

Then you simply retrieve the new Checkin instances from the source and save them to the destination. It's really a very simple but nevertheless effective design that still gives you loose coupling - you can swap out one ICheckinRepository type for another at any given point.

With an SOA (or we can just call it Web Services), you actually have a physical service endpoint that implements ICheckinRepository as opposed to a class (the service internally uses a class, but the client doesn't know about this). So to support the scenario described above, you would create one service instance that implements the TFS repository, a second that implements the SVN repository, and have your sync application simply point to two different URLs for the source/destination, using the same interface for each.

It sounds kind of cool, but keep in mind that you now have to maintain 3 completely separate and distinct applications. You could get it down to 2 - you could implement both the TFS and SVN endpoints in a single WCF project - but still you need to maintain at least two applications, the client will always be separate. So if you make any changes to the interface, you have to rebuild and retest both apps.

And then you have to worry about how to implement security, reliable messaging, fault contracts, alerts, etc. All things that you wouldn't really care about in the single-app architecture.

There's a significant amount of overhead involved in maintaining the SOA version of this, and all to perform a task that's really not that complicated - read checkins from source, write checkins to destination. I don't think it's worth it.


Now I'll add one thing, using the Source Control example. There is a variation of this problem where it possibly would simplify your life to create a Web Service, and that is when you need to use VCS A (let's say TFS) for some projects and VCS B (let's say SVN) for other projects.

In this scenario, you want to provide a single, unified "Version Control" interface that clients can use without having to worry about which project is in which VCS. This is an annoying problem to solve using traditional approaches; you might build your own custom SC add-in or shell extension to do the work, but that's a lot of deployment and maintenance to deal with. If any standalone applications depend on it, the problem grows worse.

Here is where a Web Service becomes incredibly useful. You can create a single service that hides the real VCS implementations and provides one interface that automatically updates from or commits to the correct VCS based on the project or project type. Instead of having an architecture that looks like this:

                                       +-----> SVN
+-------------------------------+      |
| Application -----> VC Library-|------+
+-------------------------------+      |
              CLIENT                   +-----> TFS

You have one that looks like the following:

                                       +-----> SVN
+-------------+       +------------+   |
| Application-|-----> | VC Service-|---+
+-------------+       +------------+   |
     CLIENT               SERVER       +-----> TFS

What's different? Well, the "VC Service" is centralized. In the top version, we have to package the VC Library with every instance of the application, which means headaches when it needs to change. In the second version, we only need to make a single change on the server. We can completely change TFS over to, I don't know, Rational or something, without any of the clients ever even knowing about it.

The difference between this and the original example is that in this case, there may be several clients all using the same service. In the scenario posed by this question, there would really only be one "consumer" of the web service - the Sync Application which will probably still run as a Windows Service or a scheduled task. The benefit of that is slim at best. The benefit in the second example here is much clearer. You can design a single application to interface with a single VC service and let the service sort out the implementation details, and if you change your VC, you don't have to update or redeploy the app.


I hope this is a good explanation of when and why you would, or would not, use Web Services to solve a particular problem, of where they tend to be most useful in the real world. I don't think the cost outweighs the benefit here, but there are of course many instances when it will.

Aaronaught
That is a VERY good explanation. +1! What books cover these sort of topics? This is extremely useful knowledge. Funnily enough, some of what you've said is being implemented in a project at work.
dotnetdev
@dotnetdev: To tell you the truth, the only dead-tree book I ever read on this topic was "Service Oriented Architecture" and I couldn't even make it through the first half. :P Most of what I've learned comes from the MSDN and MVP blogs and just being out there in the trenches. There probably *are* good books, but any recommendations from me would just be guessing; let me know if you find any. ;)
Aaronaught