简体   繁体   中英

ASP.NET MVC consuming WCF

My ASP.NET MVC 2 controllers are currently instantiating service objects in their constructors by passing repository instances that are instantiated by Castle Windsor. I have unit tests that call the controller actions after passing Moq instances of the repositories to the controller's constructor.

I want to allow a third-party UI to access these service objects through WCF.

It occurred to me that converting my existing Service layer into Web services or even adding a new Web service layer between the UI and the existing Service layer will break my unit tests unless I find a way to bridge that gap.

I was trying to work out a solution where my UI was coded against an interface of the service layer (it already is) and I could use DI to pass the Web service implementation at run-time and pass the existing implementation during unit testing. The Web service implentation would simply call the existing implementation.

Questions:

  1. Is such an approach advisable / possible?
  2. Are there any examples of this in a tutorial or open source project?

EDIT:

I believe I have a workable solution now thanks to the suggestions below. I created a WCF Service Application that uses the existing service interfaces from my domain model. The WCF implementation is a class where the constructor takes repository instances from Ninject 's WCF extension and creates an instance of the service from the domain model. Each method/function in WCF simply calls the same method/function from the existing service layer.

There were some caveats. For example, I can no longer pass a reference to my ASP.NET MVC ModelState when I create the service in the controller (actually, I use Ninject to create an instance of the WCF service and supply that to the controller's constructor). The reason is that WCF is a messaging platform - changes must be explicitly communicated back with each call (ie my validation errors are now communicated back as reference parameters on individual functions/methods).

I also had to add some serialization/servicemodel references to my formerly POCO Core project.

Also, I switched from Castle to Ninject because Castle's WCF solution has a maturity level of low and I wasn't comfortable using that at this time.

Can you explain in more detail why your tests would break?

I do this type of development all the time. Services as classes => services as WCF services.

Your tests shouldn't break. A WCF Service is almost 100% contract, the underlying business code and logic shouldn't have to change.

Check out the Web Services Software Factory created by the Patterns & Practices team. It is a good way to structure your services into contract projects (data, message, service) and "business code". Once you get a better understanding of how to structure your code, you can refactor their style to something that fits you a little better. Their example tends to separate everything into lots of VS projects, which can be a little overkill for most shops. Example, I don't see many shops sharing data contracts across projects. Yes, in a perfect world, you should probably share a lot os types (like address) across projects, but I don't see it done very often. So, I tend put all my contract stuff in one VS project.

If your services are already defined as interfaces then you've got a head start.

Pass the services into the controllers as constructor dependencies, rather than the repositories. Let your DI container A) provide the repositories to the services, and B) provide the services to the controllers.

If you want to stand up your service layer as wcf services to be accessed by other applications, you'll want to use the wcf service factory to pull the concrete service implementations out of your DI container. Here's an example with windsor , it should be easy to adapt to whatever container you use.

At this point you can modify your website to either A) continue to invoke the services directly, or B) have them call back to the web services using service clients. There are pros and cons to both methods.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM