Since our middle-tier code-base is large and complex, we've attacked that complexity by making lots of simple, loosely coupled, Single Responsibility classes. We've read about Dependency Injection and expect that if we use that general approach, we'll end up with code which is both flexible and easy to test. We'd like to avoid writing the Dependency Injection plumbing ourselves however, so we've decided to leverage Autofac to help. We've also decided to use WebORB to handle the translation of our .NET objects to Flex DTOs/VOs. Using Autofac and WebORB will allow us to focus on our business logic without concerning ourselves with translating to and from AMF and writing the necessary plumbing for Dependency Injection respectively.
We've decided to create a set of service classes which Flex can access through WebORB. Since these classes are handling client requests directly, they often depend on other injected classes to handle some of the work-load. These dependencies also keep the service classes clean, small and easy to understand. We'd also like to provide these dependent classes to our service classes through Autofac.
There are problems
We've chosen two great tools to help, but we've a few problems to work out first:
- Out of the box, to use our service classes in WebORB we'll need to create default constructors in them. This is unpleasant since we'd like to inject our dependent classes as constructor arguments.
- To expose our Service classes to Flex, we have 2 options:
- Expose our service classes directly to Flex, so our client can remote to, say, WebORBAutofacTest.TestService
- Create an alias which maps to each of our service classes so our client can remote to, say, AppTestService
The problem with (1) is that our Flex clients shouldn't know about the specific classes they're using on the middle-tier. This leaves us free to modify, rename, of delete those classes without the fear of breaking our client. Although this makes (2) a better option, (2) is still a bit more work because we'll have to maintain our aliases which reside in a non compiler-checked config file somewhere.
- We have no idea how to get new instances of our service classes created and their dependencies injected. In other words, we cannot get WebORB working with Autofac.
- We want to inject dependencies into our service classes as constructor arguments (and we'd like for Autofac to instantiate these dependent classes for us).
- We'd like to expose only the interfaces implemented by our service classes to our Flex client (that's a more familiar approach on the mid-tier)
- and finally, we don't want to constantly update configuration files for AMF remoting
First go ahead and get the source code for this post so you won't have to cut and paste annoying code snippets.
Next we'll follow the ASP.NET Integration instructions in the all-around great Autofac wiki. After you've read the wiki entry, have a look at this simple ContainerSetup class below. This class is called by our Global.asax class to register our dependencies and help Global.asax implement IContainerProviderAccessor:
Here's the relevant section of my Global application class:The snippet above informs the classes in our application that the main application class Global is an IContainerProviderAccessor providing access to a ContainerProvider allowing callers to access the DI Container and resolve dependencies. We'll make good use of this property.
To tie WebORB to Autofac, we'll create and register our own custom Activator (we have to implement the IActivator interface, see the WebORB docs if you want to know more about Custom Activators) and instantiate our objects by resolving them from the DI Container.Configuration files
We now have to register our new DependencyActivator class in weborb.config luckily we'll only have to modify these configuration files once:Now we have to update 2 XML files which our Flex client will compile against. These files define how and where Flex will send data when remoting. First we'll create a new channel-definition in WEB-INF\flex\services-config.xml:Then we'll add a destination in WEB-INF\flex\remoting-config.xml:We now have Dependency Injection in our service classes via Autofac
Now we can finally modify our Flex client to use the new DependencyGenericDestination in its RemoteObjects. Notice that we're exposing WebORBAutofacTest.ITestService hey that's an interface!Solution benefits and drawbacks
Benefits to this approach:
- You get a Type passed into DependencyActivator, which works nicely with Autofac's Resolve method.
- You do not have to make any modifications to your service classes for this to work (in fact your service classes do not need to depend on WebORB or Autofac at all).
- You can expose your Service classes as Interfaces.
- Instantiation of classes that don't use Autofac will be slowed down by DependencyActivator going to Autofac first. To avoid this slow-down you'll have to pick a different destination in the relevant RemoteObjects in your Flex client
1 comments:
That is cooler than cool. It would be downright kewl, if kewl weren't so uncool.
Jim Plamondon
Technology Evangelist
The Midnight Coders (makers of WebORB)
Post a Comment