views:

192

answers:

2

I'm working with MEF right now, but the answer I'm looking for probably is irrelevant to MEF -- it's all dependency injection -- I'm just using MEF terminology as an example here.

Short background story, I read this article over at MSDN with focus on Composite Applications

In this figure there's three things, the shell, the application services and the modules. So that's a composite application.

alt text

What I don't fully get is the application services part. What's the service, what does it look like? How do you expose a service through a module and how do you consume a service from a different module?

I'd really like to see some neat small code examples, nothing fancy but something to illustrate how all this comes to life (the application services part).

A: 

Declare interface for service and export class implementing this interface. For instance you might have IPersonBuilder, declared in shared assembly. You're main module has MyPersonBuilder implementing interface and export this. All Views uses imports IPersonBuilder to call method on it, and using MEF composition they will be able to call say CreatePerson() on your MyPersonBuilder from your main module.

vittore
+2  A: 

Application Services, as far as MEF is concerned, are just another composable part. Any interface or class you can compose can act like a service.

Each service will have some interface or base class you want to implement. You can do these en masse via some type of IService interface (and use [ImportMany] to import them all), but often, you'll want different service types.

You'd then import this, as required, into your classes. For example, say you have a common interface library for services, and you provide:

public interface IDataRepostory
{
     public IList<MyType> MyTypes { get; }
}

You can then have a separate library export specific types:

[Export(typeof(IDataRepository))]
public class Repository: IDataRepostory
{
    // implement interface for this specific "service"
}

Your main program would then be able to import this as needed, and write code against it. For example, say you wanted to display customers, you'd need to load the customers from your data layer. If you wanted to load via your repository, you could import the repository into a specific portion of your application:

public class CustomersViewModel
{
     [Import]
     public IDataRepository
     {
         get; set;
     }

     // ...
}

You'd then get this service composed directly into your application.

This is considered an "Application Service" because it's an application specific implementation of some generic service - it's not a view related component, and it may be used throughout your application.

Reed Copsey
If more than 1 application service satisfies the import how would you distinguish between the two? metadata? or is there a better way? or is this just wrong. I know MEF throws an exception when this happens so do I really just want 1 interface and 1 concrete implementation?
John Leidegren
@John: You have to use [ImportMany], and then either query the service or use Metadata to determine which to use. Otherwise, you get an exception.
Reed Copsey
@John: If multiple services use the same import interface/class, then use [ImportMany] and import into an IEnumerable<T>
Reed Copsey
So everything in a composite application is an application service?
John Leidegren
Yes. That's why everything under the shell is inside "Application Services"...
Reed Copsey
It's all very neat... yet, very confusing to wrap around at first... thanks for clearing somethings out for me. I don't know what it is at the moment but this will certainly help but won't solve my problems for free. Is there anything I should be particularly careful about, and try to avoid, to maintain a good design?
John Leidegren
The biggest thing is to make sure it's very clear where and how you're pulling in "parts", and where they're being composed. CompositionInitializer is very handy if you're doing WPF or Silverlight... (See: http://reedcopsey.com/2010/03/26/mef-compositioninitializer-for-wpf/)
Reed Copsey
I'm doing old-school ASP.NET, been reading the patterns and practices advice on composite web applications to wrap my head around how to do this. You got any knowledge of how to do extensible UI and region management? There's lots of stuff for Silverlight and WPF but can't find any decent documentation that's not specific to either one. I've managed to work out the details of how to package and deploy ASP.NET apps but not how to compose the UI yet.
John Leidegren
@John: Sorry - not sure how to apply it to ASP.NET. Should be the same, though.
Reed Copsey
I'm basically taking all this composite application stuff and applying it to the ASP.NET Web Forms programming model. The packaging of web application projects as self-contained assemblies is a bit tricky but not really a big issue, and besides that it works very well.
John Leidegren