How to create the optimal infrastructure?

Topics: Prism v4 - Silverlight 4
Jan 9, 2011 at 11:07 AM

Since days I am reading and researching and still struggling how to create the perfect infrastructure. Since there are no Prism 4.0 templates as such, I came up with a strategy, but I need to be sure this is the right strategy and I would appreciate an advice from experienced PRISM/RIA developers.

I use PRISM 4.0, RIA Services 1.0 Sp1 Beta, Silverlight 4.0, Entity Framework 4.0

1) Client side

I created first a "Silverlight Business Application", which creates a Web.host and a Silverlight client application with implemented RIA authorization. The initially created Silverlight client application shall be used as the Shell project.

2) Infrastructure project (Common)

This project would contain some common Prism MEF attributes and perhaps the entity models that are auto generated by RIA as well as the Service Interface. The idea is to create a simple Silverlight Class Library, and under Properties of the project, I would select for the dropdown ‘WCF Ria Services Link ’ to point to the host.Web project that contains the Ria Services. Then after the rebuilding, I am able to see the entity models within the Class Library and these could then be shared between the prism modules to feed their ViewModels etc.

3) Service layer

Should I create the EF4 Model on the Web.host project and add the Domain Service in there? Then I would extract an interface from the Domain Service and put the interface into the Infrastructure (Common) project. The Web.Host therefore needs to reference the Infrastructure (common) project to get access to the interface. On the client side the interface may be used by MEF to retrieve or mock the service . However I am concerned about the service referencing a common project that contains also the client-side generated entities.

4) Authorization

Also a bit concerned about the authorization, shall I leave everything on the Shell project? Or do I have to move anything to the Infrastructure (common) project to share it?

Since this is my first time designing with PRISM, I might have misunderstood or forgotten some aspects. Please feel free to improve my suggestions.

Your help is highly appreciated

 

Developer
Jan 10, 2011 at 6:29 PM
Edited Jan 10, 2011 at 6:31 PM

Hi,

I'm glad that you've started using prism. You might find the QuickStarts and Reference Implementations useful, especially the Stock Trader Reference Implementation, which portrays a full application, so it could be a good example of how to manage the infrastructure.

I'll add some feedback to your concerns:

1) Note that you must have a bootstrapper in order to initialize your application. You can read more about it in this article from the Prism MSDN documentation.

2 & 3) What you're mentioning seems a valid approach. You could also add different infrastructure projects, one for the entities from the domain services, and another one for other aspects. You might find the following resources useful for this:

4) That depends on whether you will need to use authorization from within different modules, or just from the shell. Another possibility would be to create an authorization module, and make other modules have dependencies on that module. You can read more about it in the Modularity chapter from the Prism MSDN documentation.

I hope you find this helpful.

Guido Leandro Maliandi
http://blogs.southworks.net/gmaliandi

Jan 12, 2011 at 10:21 AM

Hi Guido,

You are my life saver. The second link (David Hill's blog) is putting the last pieces of this puzzle together for me. I had my solution very close to his but was running into some issues that he has solved in his blog. Only one drawback has his solution. His RIA Service-proxy doesn't use any Interface, hence through PRISM he isn't injecting the Service through an Interface but rather directly on the Service type.  I am not sure how he would be able to mock the service in such case for unit testing.  It is great that RIA provides generated code for client access, but since there is no generated interface for the service, this would be indeed a big problem for mocking. Unless I don't see the wood for trees.

Otherwise I like his idea of encapsulating everything related into a module.  Previously I thought I needed to feed the data through an external service library into the module (classic n-tier approach). But since Prism is meant to keep everything encapsulated and loosely coupled, the module itself should contain everything it needs.  eg. view, viewmodel, and service-proxy in order to get its data directly from the webservice. I think thats pretty neat.

Regarding the authorization you have a valid point.  I think having a Shell authorization isn't that secure hence creating a security module to make other modules depend on makes more sense. However I am not very familiar how the security is done.  I need to observe what logic is created on the client project when I making a "Silverlight Business Application", and move those bits into an own module. In case you know a magic blog from top of your head that has already attempted this, please share. ;-)

Thanks Guido, its getting very exciting.
Houman

Developer
Jan 12, 2011 at 5:59 PM

Hi Houman,

I'm glad that my answer has been helpful for you!

In order to achieve the testability requirement that you need, one possiblility would be to create a service inside your module, which could act as a wrapper to the client generated RIA Service, and then mock that service instead when you unit test your application. Another benefit of this would be that, in case you needed to obtain a reference to that service outside the module that contains it, you could use the Shared Services approach described in this chapter from the Prism documentation. By following that approach, you could register a type mapping that would export your service implementation with an interface as the contract type, and then when you resolve that interface, you would obtain an instance of your service implementation. That way, you could aid testability in your application, while using WCF RIA Services.

As for authorization and security, there isn't guidance on Prism regarding that, but you could leverage your own mechanism, or use something like EntLib's Security Application Block. Additionally, you could check some of the following authorization-related threads, which might be helpful for your scenario (especially if you plan to show a login page before loading the main portion of your application):

I hope you find this helpful.

Guido Leandro Maliandi
http://blogs.southworks.net/gmaliandi

Jan 14, 2011 at 11:49 AM
Edited Jan 14, 2011 at 4:38 PM

Hi Guido,

First of all I greatly appreciate the sources you have sent to me regarding the logging scenarios. I will definitely dig into that.

I have investigated further into your suggestion of creating a Service wrapper inside the module. The first thing that came up to my mind was, where do I put the interface? It should be somewhere where the whole application would be able to access it. Hence I have created it on the Infrastructure project, which is referenced by all modules anyway to get the MEFattributes such as [ViewExport] etc.

But then when I wrote the first method inside the interface, I realized I don't have access from the infrastructure assembly to the models.  Therefore a simple void ContactModel GetContact(int id); wouldn't even be compiling anymore since the interface has no reference to the Generated_Code from RIA.  Now where do I put the interface, inside the module has little use, since I need the contract to be visible to every module in order to mock it with a MockService later on.

And here I am back to square one. :-(

Do you have any idea how to design this better?

Update: I came up with a solution and would like to discuss it. I have removed the Ria-Link from the Module project. Instead I have made the Infrastructure project linking to RIA services. So the Generated_Code lies now inside the infrastructure project, hence the interface can see the metadata for the classes.
This would imply that all the services including their respective interfaces must reside also inside the Infrastructure project.  Since all Modules and the Shell reference the infrastructure project, they all would have access to the metadata and the interfaces.  So that works but...

Drawbacks:
1) All modules have access to all services inside the infrastructure project. The services aren't encapsulated inside the Modules respectively. Now it looks more like the traditional n-Tier architecture.

2) Since all modules have access to all services, Services could be mistakenly instantiated instead of injected by Bootstrapper. (Shift of responsibility)  This might have endangered the loose-coupling concept of Prism.

3) Utilizing the ServiceLocator makes little sense now that everything can see all the services anyway.


What are your thoughts?

Many Thanks,
Houman

Developer
Jan 14, 2011 at 4:28 PM

Hi Houman,

The approach of putting the service interfaces in the Infrastructure project of your solution is appropriate, since as you've mentioned, it should be available throughout all your modules. You can check the Stock Trader Reference Implementation, in which you can see an example of the service interfaces being placed in the Infrasrtucture project.

As for the RIA Services, one possible workaround would be to include the RIA Service reference in your Infrastructure project, so that you can access the client generated code in all your modules. That way, you could access the types defined in your RIA Service across your modules.

Another possiblity would be not to return the client generated classes in your service wrapper. That is to say, you could define your own classes that represent the data obtained from the WCF RIA service calls, and have that class defined in the infrastructure service. That way you would only need a reference to the WCF RIA Service in the concrete implementation of the service, not in the interface, which would also allow the service interface to be decoupled of the WCF RIA Service.

I hope you find this helpful.

Guido Leandro Maliandi
http://blogs.southworks.net/gmaliandi

Jan 14, 2011 at 4:44 PM
Edited Jan 14, 2011 at 5:21 PM

Hi Guido,

I was updating my former post, while at the same time you were replying to the original post. In fact I went the first path you had suggested and it works fine. But it introduces some concerns that shared above, but if you approve it, I am happy with it.

Your second suggestion regarding having to create extra classes to represent the RIA generated classes, while tempting, would create a new problem that I tried to avoid in first place by using RIA -> State Change Tracking. Perhaps one of the most painful tasks. :)

I think I will stick to putting the Services and IServices into the Infrastructure project and be careful to use DI container for retrieving instances. That should be clean enough. :)

Thanks for sharing,

Houman

Developer
Jan 14, 2011 at 5:00 PM

Hi Houman,

Please note that the first path I've suggested involves placing the RIA Service Reference and the Interface for your wrapper service in the infrastructure project, but the actual implementation of your wrapper service would be in your Module, which would act as the provider for that service, consuming the RIA Service to expose the operations that involve it. If you later wish to modify the way you expose that operations, you would then be able to modify the implementation in that module, or replace it by other module that has a different implementation, and so forth.

I hope you find this helpful.

Guido Leandro Maliandi
http://blogs.southworks.net/gmaliandi

Jan 14, 2011 at 5:28 PM

You are right Guido,

While I was developing it I realized I could just leave the actual Service implmentation inside the module. Hence the services won't be exposed to all modules (draw back 1 and 2 are now solved).

And since the actual service implemention is again encapsulated inside the module, making use of ServiceLocator becomes again attractive.  (drawback 3 also retracted)

Fantastic :)

Thanks for your help,
Houman

Jan 27, 2011 at 5:44 PM

Hi Guido,

 

Sorry for asking so many questions. I am working on several topics of Prism simultenously.  I need some more information regarding the Shared Services you had mentioned earlier, as its not very clear in the documentation to me.

Case:
If I have my IService in the infrastructure project and the service implementation inside ContactModule. I would also like to use the same service implementation in NavigationModule. These modules have no reference to each other.

From what I understood, I still register my Service like any other type with the interface inside my ContactModule:

protected void RegisterViewsAndServices()
{
   _container.RegisterType<IService, IContactService>(new ContainerControlledLifetimeManager());

}

Now in order to resolve it inside the NavigationModule all I have to do is to get the same instance correct? Actually since services are state-less I could as well get a new instance, shouldn't really make a difference, right?

var service = ServiceLocator.Current.GetInstance(IService);

Wouldn't it be the same as if I did a _container.Resolve<IService>(); 
The only difference would be that the former gets the same instance while the latter instantiate a new one from the interface, correct?

There is also a ServiceLocator.Current.GetService() ??  :)

What is the best strategy in your opinion?

Many thanks,
Houman

Developer
Jan 27, 2011 at 7:44 PM

Hi Houman,

The Common Service Locator provides an abstraction over Inversion of Control containers and service locators. For example in Prism, there is a MefServiceLocatorAdapter and a UnityServiceLocatorAdapter that provide a means to access the respective functionality from the containers to acheive service location. Therefore, there shouldn't be a difference between calling

ServiceLocator.Current.GetInstance(IService);

and

_container.Resolve<IService>();

since the IUnityContainer.Resolve method is mapped to the IServiceLocator.GetInstance method (and their generic counterparts).

Both of them will return a new instance or a singleton instance of your service, depending on whether you have registered your service as a singleton or not.

As you've mentioned, in case your service doesn't hold any state, registering it as a non-singleton wouldn't cause problems in the functionality of your application.

I hope you find this helpful.

Guido Leandro Maliandi
http://blogs.southworks.net/gmaliandi

Jul 28, 2011 at 5:56 PM

Hey Guido,

I am not sure I follow the entire solution of this issue, is there a way you can provide a skeleton project of what you mean when you say create the service wrapper in infrastructure project.  

Not sure how to do that.  Can you help please.

Developer
Jul 28, 2011 at 6:53 PM
Edited Jul 28, 2011 at 6:57 PM

Hi,

I've created a sample that portrays what I've mentioned previously in this thread. In the sample you will find a WCF service, and a Prism application which consumes that service, through the use of a wrapper that is registered in the container via an interface mapping, acting as a shared service. Modules that consume that service don't have to reference the module that contains the actual service reference and the implementation for the wrapper service; they only have to reference the Infrastructure project which contains the interface for this service wrapper.

You can find the sample (named WCFServiceWrapperSample) here.

I hope you find this helpful.

Guido Leandro Maliandi
http://blogs.southworks.net/gmaliandi

Jul 28, 2011 at 10:17 PM

Hey Guido,

I can follow the logic in your sample fine.  My confusion lay with RIA Services.  I have created a Silverlight Application foreach module in my application.  In addition, I created a RIA Service Library foreach module, and I have them linked to the module.  Obviously, as mentioned above, that will make testing not possible.

My confusion is how do I create an interface foreach module service so I can call RIA Services.  Does my question makes sense?

 

 

Jul 28, 2011 at 10:40 PM

What I would like to see is a sample of using PRISM, SL 4, RIA Services, and MVVM.

All the examples provided by PRISM do not necessary support all 4 features, and all the discussions around RIA Services and PRISM, do not really show you a good example.

I would love it if you can provide a very simple skeleton project with the "optimal" solution structure for this.

Even "Stock Trader RI" does not use RIA Services, it used hard coded data which is not really a very good example, or helpful to me.  

Can you provide such an example.

 

 

Jul 28, 2011 at 10:41 PM

Hi Bishman,

 

Getting RIA Services in a proper service utilizing PRISM is  not a sprint but a marathon.  It needs some time to really grasp it.

One example how to create proper Client side Services that wraps the RIA DataContext, is John Papa's execellent example:

http://channel9.msdn.com/Series/Silverlight-Firestarter/Silverlight-Firestarter-2010-Session-4-MVVM-Why-and-How-Tips-and-Patterns-using-MVVM-and-Service-Pat

 

You can also download the code there and get started. Your auto generated client code shall live in your Infrastructure (common) module.  That way all your modules have access to the entities (models) + your custom created IService/Service.

Regards,

Houman

 

Jul 28, 2011 at 10:46 PM

Regarding your second post, I started with Prism in November 2010. It is not easy, but it is the most powerful composite/MVVM framework you may find.  You need patience and have to do each sample one-by-one to grasp it further.

Also download http://prismtk.codeplex.com/  . This training kit helps you to understand the framework much better.

RIA Services is outside the responsibility of PRISM.  You need to take care of your service yourself. Follow the link from John papa and learn how Ria works. Once you have done all these bits you start understanding the whole picture piece by piece.

 

Regards,

Houman

Jul 29, 2011 at 9:57 PM

Thanks so much for taking the time to respond Houmie.

I understand what you are trying to say.   I downloaded the Training Tool kit and I am working my way through the examples.

All I am trying to figure out is how to structure the application, and use Repository Pattern in PRISM.

I am not sure how to create the IService/Service from my RIA Services in the infrastructure project.

That is the only area I am struggling with.  

Any help you can provide will be greatly appreciated.

 

 

Aug 8, 2011 at 4:27 PM

Hi everyone!

Looking through your discussion and progression so far, this might come a bit late, but still, the good news is, that in the mean time Templates to get started with Prism/MVVM/MEF are available from here:

http://blogs.msdn.com/b/dphill/archive/2011/03/04/prism-template-pack-1-4-now-with-mef-support.aspx

I thought it is a good idea to publish this, it really took me some time to get to the right place.

Aug 10, 2011 at 3:33 PM

@Bishman have you checked out that Firestarter link I had sent you above? Go there and download the example by John papa.  He also has a video and talks through it.  His example is often taken as the lead example in RIA forums.  He has a bookstore and has encapsulated the DataContext into a proper Service and IService.

@Peter, thats great news. It was about time for a template.  But I see loads of people have issues with path-too-long problem, is this sorted by now?

Developer
Oct 12, 2011 at 3:50 PM
Edited Oct 12, 2011 at 3:57 PM

Hi,

For those concerned with this issue, you could check the following blog post, which provides guidance on how to use WCF services with Prism in Silverlight:

Using WCF services in Prism Silverlight applications

Also, you might find the following blog post by David Hill useful, as it provides insight on how to use WCF RIA Services with Prism:

Prism And .Net RIA Services

I hope you find this helpful.

Guido Leandro Maliandi
http://blogs.southworks.net/gmaliandi