Get current web host and app directory from class library - asp.net-mvc

I want to send an email confirmation from my service layer (class library). This can be triggered from an asp.net mvc controller or a wcf service.
How do I build the Url from the service layer?

The service layer shouldn't have knowledge of how urls are constructed in your web application, especially because those rules can easily change. Also this makes your service layer tightly coupled to the web layer and less reusable. What if tomorrow you wanted to reuse this service layer in a desktop application?
IMHO that's an information that should be passed from the controller to the service layer.

Related

Web API calling Web service

I have a .net Web API 2 application that I need to use to call an web service (asmx) just to see if the web service is up and running correctly. I am a believer in architecture, so with that in mind I am not sure where to put the call to the web service. I found a post that suggested that I put this in the repository layer. Is this the correct location for that?
I would say its more of a personal preference + project specific; IMO you can place that web service in repository if it acts as a data-store or you could place it in business layer of the service does more of a business related stuffs.
But one thing I would do for sure is to create a wrapper/abstraction over this service before using it in any layer so that:
I can inject this dependency in the layers its being used
Unit testable code - DI and mockable
No changes in the layers where this is being consumed in case there is any change in service- for eg, asmx1 to asmx2 or change in asmx service to wcf or REST etc.
Not sure whether you will be able to find a specific answer to this, this is kinda arguable subject as opinions might differ according to personal preference

Design Choice: WCF or Service Stack?

I have three core applications that have their own business functions (networks, active directory and helpdesk). Each are running ASP.NET v2 or v3 and have their own respective databases. However, the application functions have merged a bit so models were recreated in each application and app logic along with it. So now I have some difficult to maintain code. So here is my question:
Is porting my models and repositories over to WCF a reasonable choice for this type of architecture?
Is using a service stack such as serialized json calls a better choice? I'd imagine this would be faster than setting up a central wcf app.
I'm not too familiar with communication between asp.net mvc web apps so please point me in the right direction.
I would recommend developing a service layer per the design pattern described by Fowler. This service layer encapsulates the various domain models and repositories and handles interactions between different domains/models. This will be an assembly and not a WCF or any other type of web service. If you require a WCF web service then it will be a very thin layer which basically has a contract that mimics the service layer and only purpose is to provide a web service interface or API.
There are a couple of ways an MVC application can interact with your service layer. If you are creating view models in your Controllers then it can access the service layer assembly directly. There is added overhead to calling it through a web service that is most likely not necessary in this case. Using this approach the service layer is pretty much your Model in the MVC trio.
The other way to access the service layer is from the Views/client using AJAX for rich clients. In this case you would use MVC to put a REST API on top of your service layer so that you can make AJAX POST's, using something like JQuery, directly to the web service to update and retrieve data for the web page.
Note with this architecture you can use a combination of both approaches. You may access the service layer directly from the Controller to render some initial pages and then use the web service REST interface for AJAX calls during user interaction.

ASP.NET MVC Adding a Web Service Layer

I wanted to get some peoples opinions on adding a web serivce layer. At my work, we want to start using web services to handle some of our operations.
Our current project structure that we follow for our ASP.NET MVC apps:
MVC App (View/Controller/ViewModel/Service Layer) --> BAL (Business Access Layer) --> DAL (Data Access Layer)
The MVC app, BAL, and DAL are separate assemblies.
There is a Domain (model) assembly as well that is shared among the MVC/BAL/DAL layers.
The plan is to create a web service that will handle all security functions. This web service will be used by multiple web applications. When we make changes to the Security Web service we only want to modify code in one place and not every web app. So I'd prefer if the MVC project has nothing in it that is tied to a web service.
So I was thinking of adding a Web Service Layer between the BAL and DAL layers.
So something like this:
MVC project (View/Controller/View Model/Service Layer)
calls
BAL Layer (Handles caching / DB Transactions)
calls
Web Service Layer
calls
DAL Layer
What are your opinions?
A couple thoughts.
You are putting your web service layer between you BAL and DAL. This means everything will need to go through your web service, including functions which aren't related to security. I think this is adding an additional layer of complexity. If multiple websites are using the web service, create it as a stand along application/service. Then you can call the service from the different layers of your application depending on what layer needs the service. Generally you would create a Webservice wrapper with a clean interface so you can easily call the Web Service from your any layer in your application.
For the sake of discussion, lets say your web service handled validation of login and password of a user. You can connect to your webservice wrapper directly in your MVC project to see if the user data is valid, then you can log them in if it is. Later, if the user performs a function, and the business layer needs to check if the user has permissions, that layer can use the api wrapper which calls the api to see if user has permissions, and so on.
MVC APP
/ \
BAL --> Web Service Wrapper
/ \
DAL WCF WEB SERVICE
As someone who supports an application that is ridiculously layered as so.
GUI
BAL
DAL to WebService
Webservice
WebBAL
WebDAL
I would suggest putting your GUI as close to your webservice as possible.

Get Base URL from service layer

I'd like to be able to get the url that the app is hosted on. There will be various ways that clients will access the service layer, through an asp.net mvc app, wcf (hosted on the mvc app).
My service layer is in a dll. Is there any way that I can get the url pointing to a specific action when a remote client uses either entry points to the system?
It is possible - but not a good thing to do. You are binding the business layer to an implementation detail which is higher layers and business layer should have no knowledge of.
You can use various OperationContext.Current properties (depending on your binding) to get to the address.
For example, OperationContext.Current.IncomingMessageHeaders can be used for HTTP or OperationContext.Current.Host.BaseAddresses if there are base addresses. You just need to evaluate which one provides the address you are looking for depending on your configuration.

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:
Is such an approach advisable / possible?
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 (i.e. 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.

Resources