PDA

View Full Version : Architecture best-practices?


jmiller
10-25-2005, 11:01 PM
Hello.

We are just beginning to integrate Spring.NET into our C# WinForms application. We're debating the best way to expose Spring to our projects and we haven't found much best-practice advice on setup. As I recall, Rod Johnson suggests never depending on Spring... but I don't know how that looks in C# WinForms.

Our application consists of 7 project assemblies. Instead of adding references to Spring .dll's to all of the projects and spraying Context code etc., we're debating creating one project containing only Spring/IOC related classes and adding references to that project. We would then expose whatever we needed to from Spring from this project.

Are there any obvious gotcha's, best-practice guidelines, or experiential examples that anyone would like to share regarding this architecture?

Thank you very much for your consideration.

Joe

Mark Pollack
10-29-2005, 02:50 AM
Hi Joe,

In a previous post I mentioned that in WinForm apps you will probably tend to see more use of Spring code inside the application code than you would in the case of a server side application because you need to do things in response to user actions - unlike the server where everything is wired up in advance. It also depends on how much value you feel you get out of using features like the MessageSource or eventing facilities in IApplicationContext that fall outside pure non-invasive dependency injection. In ASP.NET we can plug into the infrastructure such that 'new' by ASP.NET also takes care of dependency injection. That isn't so straightforward in the winforms model - the new composite ui block seems to offer something there - though one can work around it by not calling 'new' and asking spring directly for the object and/or configuring nested controls by calling ConfigureObject.

Nevertheless you can keep the exposure to Spring to a minimum, say just calls to ContextRegistry.GetObject where needed - where you need to create a new view in response to user actions or to grab resources like strings and icons. One can create a base win form class to centralize those calls even more so you don't see it used all over the place - this is something that we should be providing though .....

Hmmm, seven assemblies for a WinForms application sounds like a lot to me - why so many? The approach you suggest sounds like introducing a new factory layer - this is exactly the type of code that Spring is there to alieviate you from. If you want to introduce a lightweight layer that isolates you from Spring - but you shouldn't really have to let one of your projects be the 'Spring gateway'...

I've taken the approach of a MVC architecture for WinForm apps in a few projects now. Each element in the MVC triad can be configured via Spring. The view is kept very thin and calls into the controller which in turn typically calls a service method to communicate with a middle tier. The server then can reply (sync or async) and the client will update the model etc. Fairly standard MVC stuff.

The service methods should ideally defined in an interface so you can have a nice decoupling between the GUI and middle tier. This lets you do things like replace the real service with test-stub implementations to bootstrap GUI development while the server side team is busy implementing 'the real thing'. Also, it will let you easily add AOP aspects to perform logging/timing etc. By chaning config files you can do this very easily.

If you keep the actual winform layer pretty thin - i.e. no business logic except maybe for direct screen manipulation that doesn't need to pass through the controller, you can do some unit/functional/integration testing by driving the controller layer. With NUnit or MbUnit then you can have developers write some basic smoke tests. This approach obviously isn't unique to Spring. I've had a good experience with Mercury QuickTest - it lets you do 'asserts' within a robot driven testing approach - though it is still harder in my experience to keep up maintaining those tests than to write integration style NUnit tests which give a lot of value for relatively little effort in comparison.

The configuration template features of Spring (abstract=true and specifying a parent) also work nicely to allow some flexibility in changing some global options that all forms or controllers share. It is relatively straightforward spring usage.

I've started porting a little bit of the Spring.Java rich client - so you can define things like a splash screen and the initial form to display as well as simple shell for mdi screen etc. Also I wrote an 'ObjectDataSource' so you can bind business objects to a data grid - which is pretty useful if you have gone down that route. "one of these days" i'll stick it in the cvs sandbox...

I've used Microsoft's User Interface Process 2.0 and modified it to make its views and controllers configurable via Spring. The navigation and 'state' facilities it offered were not that compelling to me - maybe other people find value in it. The new Composite Application Block is WinForm focused but I have not played around with it - just read the api docs and other articles right now. However, it is for .NET 2.0 - there maybe a backport though - one would have to check.

One best practice is to have at a minimum 3 assemblies/projects. One that contains just a Main class that is of the type Windows Application (i.e. makes an .exe) The bulk of the code is in a project of type ddl, this is so that you can write NUnit tests against that code in the third project. The only other projects you should need for the GUI would potentially be shared interfaces for remoting or some other means you communicate with the middle tier.

Hmm well long message - let me know if anything in particular struck a chord and you would like to know more and/or see Spring provide something in particular for WinForm applications.

Cheers,
Mark

ivolved
11-14-2005, 09:56 PM
Mark,
I think there would be some benefit to a Spring MVC for winforms project, if nothing more than to encourage "best practices". I too tried to use the UIPAB but there was just too much to grasp to get my project started quickly so I ended up enforcing MVC within my own code. All events that have handlers in my forms basically do little more than make a call to the controller which calls the business tier (as necessary) and passes information back to the form with setters or opens a new form as needed. (Very similar to how struts works). The only major difference is I don't use configuration files, but who really needs them.

I use the Facade pattern for my business tier (it basically handles all the calls to the DAOs, Security, and Logging for each action). The Controller passes Command Objects to the Facade that know their name, and the privilege a user needs to execute them -- one privilege for each Command.

The benefit of using the Facade pattern materialized when I needed to make the business logic run on a server with several clients accessing it. All I had to worry about was changing one call that initialized the Facade. (I later learned that .net Remote Proxies allow you to use a remote object without even making that change through the configuration file).

I ran my unit test suite and everything worked just as beautifully as before.

I believe that it would be great if we could encapsulate this architecture within Spring. Maybe after I take some time with the nHibernate integration, I can look at doing the same with Winforms.

I think the API and usage shouldn't stray too far from Springweb. Actually, I think that the exact same code base should be usable in a web and a Winform application (with changes in the configuration). First we could roll our own and then we can integrate with the CAB.

Aleks Seovic
11-15-2005, 12:28 AM
Hi,

There is a plan to do Spring.WinForms module implementation that would be very similar feature-wise to Spring.Web (data binding, localization, and validation frameworks would be pretty much shared, you would be able to inject dependencies into your forms and controls, etc.)

We also want to add Eclipse-like plugin support to WinForms apps, and whatever else we can think of that would simplfy development of WinForms applications.

The goal is exactly what you mentioned -- to be able to reuse as much as possible between Windows and Web apps. Service and data layer, localization resources, validation configuration etc. should be easily reused. We'll also implement WinForms version of SpringAir in the process, so we have a reference application that shows how to architect your app to achieve this.

Later,

Aleks

jmiller
11-16-2005, 04:30 AM
Thank you to all for your responses!

On the "seven assemblies" bit... I probably made that sound more complicated that it is. We really have a decent MVC approach going with some utility-like, universal projects thrown in. Constantly refactoring though... And we've had some success and fun incorporating NUnit.

We actually have started down the path of a Spring gateway. We'll see how it goes. We're figuring that we won't need a lot of the behavior that implementing some interfaces will get us. We mainly want Singleton and Observer over everything else... Again, we'll see how it goes!

One of our guys has been working with Composite Application Block. I don't know much more than what he's talked about, but you can implement the Observer publish/subscribe with source level attributes. But he doesn't know if auto-wiring with an instance type is possible... We're angling to be able to incorporate both in the future.

BTW - we're all Java certified guys (J2EE) working in .NET (WinForms) for the past year. That alone has been enough to keep us busy! I really appreciate responses and your hard work.

- Joe