In my solution I have a Web application project and a Class library project that contains all the business logic and this also acts as a data access layer as I am using Entity Framework. This means that I have my edmx in this layer itself.
I have some 34 classes in this class library project and at an average 6 public methods in each class. These classes were getting called directly from the web application until now. No problems. Now I want to introduce the WCF Layer between the UI and the Business logic layer.
This means I will have to write wrapper methods for all my methods and expose them in a WCF Service. Does this mean that 34 * 6 = 204 methods (approximately) will appear in my service layer as Operation Contracts? As per OO, I think this is too large a class and so it feels wrong.
I know there is the Generic Service design pattern, but is there anything else that I am missing? Please advise.
You could try RIA services
http://www.silverlight.net/getstarted/riaservices/
What I'm using is this.
Create a WCF service
2.1. Point the SVC service to your implementation like:
<%# ServiceHost Language="C#" Debug="true" Service="BusinessLayer.Service" %>
BusinessLayer.Service is a class in your Class project. (reference in service is needed)
2.2. Point the service behavior to the contract:
<service behaviorConfiguration="ServiceBehavior" name="BusinessLayer.Service">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="basicHttpBinding" contract="BusinessLayer.IService">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
</service>
Edit the name (BusinessLayer.Service) and contract (Businesslayer.IService)
Create the contract interface BusinessLayer.IService (in your Class project):
namespace BusinessLayer
{
[ServiceContract]
public interface IService
{
[OperationContract]
void DoWork();
}
}
Modify the existing implementation which uses the interface (here is your existing code):
namespace BusinessLayer
{
public class Service:IService
{
Public void DoWork()
{
}
}
}
Why do you want to wrap the entire business logic layer in a WCF layer? I would look very closely at your reasons for this before jumping into this new approach. Do you have physical reasons that you simply can't get around like the business logic that accesses the database needing to be outside the DMZ? If so, ok. But if not, I'd think twice about going down this approach to start with.
Having said that, if you have no other choice, I'd avoid the monolithic WCF class that wraps every public method that your UI needs. First off, I'd introduce an interface on the web application side so that you can depend on abstracts in the UI rather than concrete implementations. Further, I'd look into using WCF REST services. You can use ServiceRoute's to avoid having to introduce any *.svc files. Then you can decorate the methods you want to expose with WebGet/WebInvoke attributes. This could potentially save a lot of coding.
Well,
We have a similar application but the number of classes is even higher. Your concern here is that you are reluctant to provide serialization (that is what is needed to pass objects by WCF) to core classes of your business logic server.
Provided you have a classical three-tier application where business logic server and a client access the same database. What you need to do is simply 1) ensure all your objects have a unique identification (this could be a string or Guid) and 2) pass object ID in all WCF calls. What that means is that you DO NOT expose any classes on WCF side.
This might be quite is safer since you have a web application.
It is wrong. Your services should not have much more than 20 operations. If you need exactly same operations you should create contract and service wrapper for each business class. This usually results in chatty interfaces which are not good solution for distributed scenario. In that case you should model your service layer as facade which compounds several calls into one.
Related
We came across a god object in our system. The system consists of public service exposed to our clients, middle office service and back office service.
The flow is the following: user registers some transaction in public service, then manager from middle office service checks the transaction and approves or declines the transaction and finally manager from back office service finalizes or declines the transaction.
I'am using the word transaction, but in reality those are different types of operations like CRUD on entity1, CRUD on entiny2... Not only CRUD operations but many other operations like approve/send/decline entity1, make entity1 parent/child of entity2 etc etc...
Now WCF service contracts are just separated according to those parts of the system. So we have 3 service contracts:
PublicService.cs
MiddleOfficeService.cs
BackOfficeService.cs
and huge amount of operation contracts in each:
public interface IBackOfficeService
{
[OperationContract]
void AddEntity1(Entity1 item);
[OperationContract]
void DeleteEntity1(Entity1 item);
....
[OperationContract]
void SendEntity2(Entity2 item);
....
}
The number of those operation contracts are already 2000 across all 3 services and approximately 600 per each service contract. It is not just breaking the best practices, it is a huge pain to just update service references as it takes ages. And the system is growing each day and more and more operations are added to those services in each iteration.
And now we are facing dilemma as how can we split those god services into logical parts. One says that a service should not contain more then 12~20 operations. Others say some different things. I realize that there is no golden rule, but I just would wish to hear some recommendations about this.
For example if I just split those services per entity type then I can get about 50 service endpoints and 50 service reference in projects. What is about maintainability in this case?
One more thing to consider. Suppose I choose the approach to split those services per entity. For example:
public interface IEntity1Service
{
[OperationContract]
void AddEntity1(Entity1 item);
[OperationContract]
void ApproveEntity1(Entity1 item);
[OperationContract]
void SendEntity1(Entity1 item);
[OperationContract]
void DeleteEntity1(Entity1 item);
....
[OperationContract]
void FinalizeEntity1(Entity1 item);
[OperationContract]
void DeclineEntity1(Entity1 item);
}
Now what happens is that I should add reference to this service both in public client and back office client. But back office needs only FinalizeEntity1 and DeclineEntity1 operations. So here is a classic violation of Interface segregation principle in SOLID. So I have to split that further may be to 3 distinct services like IEntity1FrontService, IEntity1MiddleService, IEntity1BackService.
The challenge here is to refactor your code without changing large portions of it to avoid potential regressions.
One solution to avoid large business code with thousands of lines would be to split your interfaces/implementations into multiple parts, each part representing a given business domain.
For instance, your IPublicService interface could be written as follows (using interface inheritance, one interface for each business domain):
IPublicService.cs:
[ServiceContract]
public interface IPublicService : IPublicServiceDomain1, IPublicServiceDomain2
{
}
IPublicServiceDomain1.cs:
[ServiceContract]
public interface IPublicServiceDomain1
{
[OperationContract]
string GetEntity1(int value);
}
IPublicServiceDomain2.cs:
[ServiceContract]
public interface IPublicServiceDomain2
{
[OperationContract]
string GetEntity2(int value);
}
Now for the service implementation, you could split it into multiple parts using partial classes (one partial class for each business domain):
Service.cs:
public partial class Service : IPublicService
{
}
Service.Domain1.cs:
public partial class Service : IPublicServiceDomain1
{
public string GetEntity1(int value)
{
// Some implementation
}
}
Service.Domain2.cs:
public partial class Service : IPublicServiceDomain2
{
public string GetEntity2(int value)
{
// Some implementation
}
}
For the server configuration, there is still only one endpoint:
<system.serviceModel>
<services>
<service name="WcfServiceLibrary2.Service">
<endpoint address="" binding="basicHttpBinding" contract="WcfServiceLibrary2.IPublicService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8733/Design_Time_Addresses/WcfServiceLibrary2/Service1/" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="True" httpsGetEnabled="True" />
<serviceDebug includeExceptionDetailInFaults="False" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
Same for the client: still one service reference:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IPublicService" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:8733/Design_Time_Addresses/WcfServiceLibrary2/Service1/"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IPublicService"
contract="ServiceReference1.IPublicService" name="BasicHttpBinding_IPublicService" />
</client>
</system.serviceModel>
This allows to refactor your server side by splitting your huge services into multiple logical parts (each part associated with a given business domain).
This doesn't change the fact each of your 3 services still has 600 operations, so the client proxy generation would still take ages. At least your code would be better organized server-side, and the refactoring would be cheap and not-so-risky.
There is no silver-bullet here, that is just code reorganization for better readability/maintenance.
200 services with 10 operations for each vs 20 services with 100 operations for each is another topic, but what is sure is that the refactoring would require way more time, and you would still have 2000 operations. Unless you refactor your whole application and reduce this number (for instance by providing services that are more "high-level" (not always possible)).
Having too many operation contracts doesn't make sense in a given service as it will leads to maintenance issues. Having said that if operations like Add(), Delete, Update(), AddChildItem(), RemoveChildItem(), etc are supposed to be together, then don't worry about operation contract going up to 30-40 in number. Because things that should be together should come out from a single interface (cohesion).
But 600 operations in a given service contract is really overwhelming number. You can start identifying the operations:-
That are required to be together
And that are not required to be together in a given service.
Based on this you can split the operations into different services.
If some of the methods are not used by client directly, then consider exposing the method based on the BUSSINESS logic (as also suggested by "Matthias Bäßler").
Say you want to expose the MoneyTransfer functionality. Then you are not required to expose
SendEmail()
DebitAccount()
CreditAccount(), etc in the service used by your web application.
So here you can expose just an aggregate service to your web application. In this case it may be IAccountService with methods like just
TransferMoney()
GetBalance(),
Internally in your implementation you can create other service which provides related operation like:-
SendEmail()
DebitAccount()
CreditAccount(), etc. required for IAccountService. MoneyTransfer() method.
This way, the number of methods in a given service will come down to a maintainable level.
I don't have experience with WCF but I think god classes and overloaded interfaces seem to be a general OOD problem.
When designing a system you should look for behaviour (or business logic) instead of data structures and operations. Don't look at how you're going to implement it but how the client would use it and how he would name it. In my experience, having the right names for the methods usually provides a lot of clues about the objects an their coupling.
For me the eye-opener was the design of the Mark IV coffee maker, an excerpt from "UML for Java Programmers" by Robert C. Martin. For meaningful names I recommend his book "Clean Code".
So, instead of building an interface of discrete operations like:
GetClientByName(string name);
AddOrder(PartNumber p, ContactInformation i);
SendOrder(Order o);
Do something like:
PrepareNewOrderForApproval(PartNumber p, string clientName);
Once you've done this, you also might refactor into separate objects.
Your problem is not so much a god object problem, as it is a service composition problem. God objects are problematic for different reasons than huge, crud-based service interfaces are problematic.
I would certainly agree that the 3 service contracts you have described are reaching the point where they are effectively unmanageable. The pain associated with refactoring will be disproportionately higher than if this was in-process code, so it's very important you take the correct approach, hence your question.
Unfortunately, service composability in soa is such a huge topic it's unlikely you'll receive massively useful answers here; though obviously useful, the experiences of others will unlikely apply to your situation.
I have written about this on SO before, so for what it's worth I'll include my thoughts:
I find that it's best if service operations can exist at a level where
they have business meaning.
What this means is that if a business person was told the operation
name, they would understand roughly what calling that operation would
do, and could make a guess at what data it would require to be passed
to it.
For this to happen your operations should fulfill in full or in part
some business process.
For example, the following operation signatures have business meaning:
void SolicitQuote(int brokerId, int userId, DateTime quoteRequiredBy);
int BindPolicyDocument(byte[] document, SomeType documentMetadata);
Guid BeginOnboardEmployee(string employeeName, DateTime employeeDateOfBirth);
If you use this principal when thinking about service composition then
the benefit is that you will rarely stray far from the optimal path;
you know what each operation does and you know when an operation is no
longer needed.
An additional benefit is that because business processes change fairly
rarely you will not need to change your service contracts as much.
I am new to WCF, I am facing concurrency related issue in my hosted wcf service (.net framework 4.0) on IIS 7 / Windows 2008 server. I did all the possibilities after googling but still not able to fix my problem. I have created and inventory service which uses Entity Framework to fetch data from SQL Server tables like ItemHeadMaster, ItemMaster etc.
I referenced this WCF in my custom user search control for searching purposes. All is running well when 2 concurrent user hit search control placed on ASP.Net page.
My code looks like this:
namespace HIS.STORESERVICES
{
[ServiceBehavior(ConcurrencyMode=ConcurrencyMode.Multiple)]
public class StoreMasterData : IStoreMasterData
{
public string GetAllItemHead(string strHospitalId)
{
using (DAL.ItemHeadMaster objItemHeadMasterDAL = new DAL.ItemHeadMaster())
{
List<STORE.MODEL.ItemHeadMaster> objItemHeamMasterList = new List<STORE.MODEL.ItemHeadMaster>();
objItemHeamMasterList = objItemHeadMasterDAL.GetAllItemHead(strHospitalId);
XmlSerializer Xml_Serializer = new XmlSerializer(objItemHeamMasterList.GetType());
StringWriter Writer = new StringWriter();
Xml_Serializer.Serialize(Writer, objItemHeamMasterList);
return Writer.ToString();
}
}
}
I did following after googling:
added in config but NO EFFECT
<system.net>
<connectionManagement>
<add address="*" maxconnection="100" />
</connectionManagement>
</system.net>`
Added in config but NO EFFECT instead it gets more slow..
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="True" />
<serviceThrottling maxConcurrentCalls="32"
maxConcurrentInstances="2147483647"
maxConcurrentSessions="20"/>
Please help
Before WCF, to construct a service for cross process communications between processes in the same host, or in the same LAN, or in the Internet, you have to hand-craft transportation layers and data serializations for target environments and specific protocols.
With WCF, you just need to focus on creating data models (DataContracts after being decorated by attributes) and operation models (OperationContracts), and .NET CLR will "create" most if not all needed transportation layers and data serializations at run time, according to the configuration defined by you or the system administration in the target environment.
The defects in your codes:
WCF typically uses DataContractSerializer, NOT Xmlserializer to serialize things, and you don't need to call it explicitly, since the runtime will do it.
For most applications, you don't need ServiceBehaviorAttribute explicitly. You must know WCF in depth before using those advantage config which is not for beginner. And I rarely used them.
Your service interface function should comfortably return complex type rather the serialized text. In 99.9% of cases, if you have explicit serialization codes in WCF programs, the whole design is very dirty if not entirely wrong.
There are plenty of tutorials of creating Hello World WCF projects, and VS has one for you when creating a new WCF application. After you got familiar with Hello World, you may have a look at http://www.codeproject.com/Articles/627240/WCF-for-the-Real-World-Not-Hello-World
BTW, WCF serialization is very fast, check http://webandlife.blogspot.com.au/2014/05/performances-of-deep-cloning-and.html
i am searching right write up why we need to use interface as Service contract in WCF. i got this url Why does .net WCF Service require the Interface and from here i came to know that we can write service contract attribute on class instead of interface.
[ServiceContract]
public class TheService
{
// more stuff here
}
config entry
<services>
<service name="YourServiceName">
<endpoint address="" behaviorConfiguration="httpBehavior" binding="webHttpBinding" contract="TheService"/>
</service>
</services>
but very disappointed that not getting all the valid reason like why people often use interface as service contract ?
so just tell me all the advantage we get when we use interface as service contract. so looking for all the valid point for using interface as service contract. so give points with example scenario too because for better understanding. thanks
As you have demonstrated - you don't need to define an interface for a service contract to get it working. However, arguable in doing so, your class is violating the principle of Single Responsibility (granted this is officially an OO principle - but in my opinion it is one of those universal principles that seems to be a good idea everywhere).
The service contract acts as the "contract" (duh!) between the publisher of the service and the clients that consume it. As such, once you have clients consuming it, you need to be very careful about any changes you make - especially if the clients may be third parties over which you have no control. In accordance with the "Single Responsiblity Principle", defining an interface that represents the contract allows you let this interface have responsibility for the public API, separating it from the implementation.
[ServiceContract]
public interface ILoggingService
{
[OperationContract]
void LogMessage(string message);
}
This implementation is a relies of the fact that all clients connect to the same instance:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class SingletonLoggingService : ILoggingService
{
void LogMessage(string message)
{
}
}
This implementation give you a new instance of the service for every call to it:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class SingletonLoggingService : ILoggingService
{
void LogMessage(string message)
{
}
}
The advantage of the interface, is that I can mess around with the implementation as much as I like (including it's instancing mode, concurrency, it's behaviour under client sessions, namespace, the name of the class etc.), and not have to worry that I'm potentially breaking any clients.
Agreed - there are ways to maintain backwards compatibility even if you define the service contract to be the class - but it's far more error prone and you are more likely to forget something. Separating the public API and it's implementation leads to cleaner code, and a smaller risk of developers making mistakes.
So far I found that MEF is going well with presentation layer with following benefits.
a. DI (Dependency Injection)
b. Third party extensibility (Note that all parties involved should use MEF or need wrappers)
c. Auto discovery of Parts (Extensions)
d. MEF allows tagging extensions with additional metadata which facilitates rich querying and filtering
e. Can be used to resolve Versioning issues together with “DLR and c# dynamic references” or “type embedding”
Pls correct me if I’m wrong.
I'm doing the research on whether to use MEF in Service layer with WCF. Pls share your experience using these two together and how MEF is helping you?
Thanks,
Nils
Update
Here is what my result of research so far. Thanks to Matthew for helping in it.
MEF for the Core Services - cost of changes are not justifying the benefits. Also this is big decision and may affect the service layer in good or bad way so needs lot of study. MEF V2 (Waiting for stable version) might be better in this case but little worried about using MEF V1 here.
MEF for the Function service performs - MEF might add the value but it’s very specific to the service function. We need to go deep into requirement of service to take that decision.
Study is ongoing process, so everyone please share your thoughts and experience.
I think any situation that would benefit from separation-of-concerns, would benefit from IoC. The problem you face here is how you require MEF to be used within your service. Would it be for the core service itself, or some function the service performs.
As an example, if you want to inject services into your WCF services, you could use something similar to the MEF for WCF example on CodePlex. I haven't looked too much into it, but essentially it wraps the service location via an IInstanceProvider, allowing you to customise how your service type is created. Not sure if it supports constructor injection (which would be my preference) though...?
If the WCF service component isn't where you want to use MEF, you can still take advantage of MEF for creating subsets of components used by the service. Recently for the company I work for, we've been rebuilding our Quotation process, and I've built a flexible workflow calculation model, whereby the workflow units are MEF composed parts which can be plugged in where needed. The important part here would be managing how your CompositionContainer is used in relation to the lifetime of your WCF service (e.g. Singleton behaviour, etc.). This is quite important if you decide to create a new container each time (container creation is quite cheap, whereas catalog creation can be expensive).
Hope that helps.
I'm working on a solution where the MEF parts that I want to use across WCF calls are stored in a singleton at the application level. This is all hosted in IIS. The services are decorated to be compatible with asp.net.
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
In Global.asax, I import the parts.
[ImportMany(typeof(IOption))]
public IEnumerable<IOption> AvailableOptions{ get; set; }
After initializing the catalog and container, I copy the imported objects to my singleton class.
container.ComposeParts(this);
foreach (var option in AvailableOptions)
OptionRegistry.AddOption(option);
EDIT:
My registry class:
public static class OptionRegistry
{
private static List<IOption> _availableOptions= new List<IOption>();
public static void AddOption(IOption option)
{
if(!_availableOptions.Contains(option))
_availableOptions.Add(option);
}
public static List<IOption> GetOptions()
{
return _availableOptions;
}
}
This works but I want to make it thread safe so I'll post that version once it's done.
Thread-safe Registry:
public sealed class OptionRegistry
{
private List<IOptionDescription> _availableOptions;
static readonly OptionRegistry _instance = new OptionRegistry();
public static OptionRegistry Instance
{
get { return _instance; }
}
private OptionRegistry()
{
_availableOptions = new List<IOptionDescription>();
}
public void AddOption(IOptionDescription option)
{
lock(_availableOptions)
{
if(!_availableOptions.Contains(option))
_availableOptions.Add(option);
}
}
public List<IOptionDescription> GetOptions()
{
return _availableOptions;
}
}
A little while ago i was wondering how I could create a WCF web service that will get all of its dependencies wired by MEF but that i wouldnt need to write a single line of that wire up code inside my service class.
I also wanted it to be completely configuration based so i could just take my generic solution to the next project without having to make code changes.
Another requirement i had was that i should be able to unit-test the service and mock out its different dependencies in an easy way.
I came up with a solution that ive blogged about here: Unit Testing, WCF and MEF
Hopefully will help people trying to do the same thing.
I am not understanding how my model can be a WCF service. It makes sense when its an Astoria partial class residing on the client that allows remote calls to do persistence calls, but a WCF service doesn't have properties for model fields that can be used to update a data store.
Even if I could factor out an interface for a model/domain object class into a separate assembly, a silverlight project will not allow me to add that as a reference.
How should my ViewModel encompass my WCF calls? Ultimately the WCF will call a repository assembly implemented in Linq-to-Sql, but apparently those entities are not my model in this scenario, my WCF classes are?
Thanks for any guidance on this.
Also, posts I have read to give a frame of reference:
http://development-guides.silverbaylabs.org/Video/Silverlight-Prism#videolocation_0
http://blogs.conchango.com/davidwynne/archive/2008/12/15/silverlight-and-the-view-viewmodel-pattern.aspx
http://msdn.microsoft.com/en-us/magazine/dd458800.aspx
When you create a service reference to a WCF service in a Silverlight project it also generates an interface for that Service, this is similar to David Wynns IFeedService in the articles you listed above. The service reference will also generate proxy objects that represent the objects used by the service (Product, Category etc).
The important thing to note is that the service interface isn't the model, it's how you access the model. Going back to David's example, his ViewModel exposes a list of items (his model), this list is retrieved using the service.
If you're looking to share code between the client and server I'd reccomend looking into something like RIA Services. If this isn't for you then I'd look at a few articles around about sharing code between the server and client (via Add as Link).
Hope this helps