Need Help in WCF-Dependency Injection in WCF - wcf

Hi I am planning too create a Broadcasting Service, which will broadcast emergency messages to user. Message can be send through
Mail
Message
SMS
I had created one interface
public interface IBroadCastingMessage
{
[OperationContract]
[WebGet(ResponseFormat = WebMessageFormat.Xml)]
bool BroadCastMessage();
string MessageBody { get; set; }
}
and two classes one for sms and one for mail
public class clsSendMail : IBroadCastingMessage
public class clsSendSMS: IBroadCastingMessage
and implement broadcast message in both of these two classes.
Now how can I call these methods with the help of DI pattern in WCF,where user will pass the object and in runtime we will decide weather we need to send message through sms or through mail
This is my service but I am getting issue with it,
public class BroadCastingMessage : IserviceInfo
{
public void IntializeService(IBroadCastingMessage obj)
{
obj.BroadCastMessage();
}
}
}
can anyone please let me know right way to achieve this?

Related

Combine wcf operation contracts

The common way in WCF is to have a service with several operation contracts. Once an operation contract is defined you better not change it anymore because there are a lot of cases in which an operation change will break an existing client. But how about having just one general or universal operation contract (One single instead of many operation contracts. In fact I know you won’t be able to combine all in one but most of them).
Here one example. That’s not the way I would finally realize it … just a simple illustration.
public enum Operation
{
Add,
Sub,
Mul,
Div
}
[DataContract]
public class Info
{
[DataMember]
public Operation Operation { get; set; }
[DataMember]
public object Data { get; set; }
}
[ServiceContract]
public interface IService
{
[OperationContract]
Info Do(Info info);
}
public class Service : IService
{
public Info Do(Info info)
{
var result = -1;
switch (info.Operation)
{
case Operation.Add:
// cast info.Data and calculate result
break;
case Operation.Sub:
// cast info.Data and calculate result
break;
}
return new Info { Operation = info.Operation, Data = result };
}
}
The main disadvantage on a universal contract is that you have to know how to pass data to the service and how to interpret the result. But this can be solved by documentation.
Currently I’m working on a project with a big client-server-application combined in one solution. It’s a big hassle to add one operation, update service references…
What speaks against to combine operation contracts? Do I have something more to consider?
Once an operation contract is defined you better not change it anymore
But how about having just one general or universal operation contract
[ServiceContract]
public interface IService
{
[OperationContract]
Info Do(Info info);
}
Though you have made an attempt to make it "universal" or generic you really haven't. That's because your service interface only accepts Info as an argument with no room for expansion.
Info has members of type Operation - an enumeration which you cannot change as you rightly stated. What happens if I want to do a square root operation down the track? Or maybe a factorial?
One approach for single method service contracts that allow for future request types is the request/response pattern. Essentially you define the WCF service contract once and it never changes even when you add new operations. There's actually no need to. The object that is passed in the Request parameter is essentially an a standard envelope in which the actual specific operation is serialised.
e.g. here I have renamed your Request to RequestEnvelope
[ServiceContract]
public interface IService
{
[OperationContract]
ResponseEnvelope Do(RequestEnvelope request);
}
[DataContract]
public class RequestEnvelope
{
[DataMember]
public IRequest Request { get; set; }
}
[DataContract]
public class ResponseEnvelope
{
[DataMember]
public IResponse Response { get; set; }
}
For example, I might want to calculate prime numbers so I would serialise an instance of CalculatePrimes into the Request member of RequestEnvelope.
public interface IRequest { }
public interface IResponse { }
[Serializable]
public class CalculatePrimes : IRequest
{
public int StartAt { get; set; }
public int CountToCalculate { get; set; }
public TimeSpan Timeout { get; set; }
}
[Serializable]
public class CalculatePrimesResponse : IResponse
{
public List<int> Primes { get; set; }
}
This approach works very well when refactoring large monolithic services with many many operations on a single WCF interface into something more manageable and significantly less long-term maintenance. Note how the actual requests and responses don't have to be actual WCF types but POCOs.

NserviceBus not loading existing saga data

I have implemented a my connector using nservice bus saga. Below is the code
public class ClientSaga : Saga<ClientSagaState>,
IAmStartedByMessages<ClientChangeMessage>,
IAmStartedByMessages<ClientContactChangeMessage>,
IAmStartedByMessages<ClientPictureChangeMessage>,
IHandleTimeout<ClientSagaState>
{
[SetterProperty]
public IClientContactChangeDb ClientContactChangeDb{get;set;}
[SetterProperty]
public IBusRefTranslator BusRefTranslator{get;set;}
public void Handle(ClientContactChangeMessage message)
{
var state=this.Data;
//Some handling logic
//Check if client is not in database then store the state
state.ClientContactChange=message;
state.ClientRef =message.ClientRef;
//if client is in the data base then
MarkAsComplete();
}
public void Handle(ClientChangeMessage message)
{
var state=this.data;
//Update or create the client depending on the situation
//check for dependencies
if(state.ClientContactChange !=null)
{
//Handle the contact change
}
else
{
state.ClientChangeMessage=message;
state.ClientRef=message.ClientRef;
}
}
public void Handle(ClientPictureChangeMessage message)
{
var state=this.Data;
//If the client is there then update the picture else store in saga
state.ClientPictureChangeMessage =message;
state.ClientRef=message.ClientRef;
}
}
public override void ConfigureHowToFindSaga()
{
ConfigureMapping<ClientContactChangeMessage>(s => s.ClientRef, m => m.ClientRef);
ConfigureMapping<ClientPictureChangeMessage>(s => s.ClientRef, m => m.ClientRef);
ConfigureMapping<ClientChangeMessage>(s => s.ClienttnRef, m => m.Id);
}
}
public class ClientSagaState: IContainSagaData
{
//i dont need these three fields
public Guid Id { get; set; }
public string Originator { get; set; }
public string OriginalMessageId { get; set; }
// the fields which i needed
public Guid ClientRef {gee; set;}
public ClientChangeMessage ClientChange {get;set;}
public ClientContactChange ClientContactChange {get;set;}
public ClientPictureChangeMessage ClientPictureChangeMessage {get;set;}
}
Now in my connector a client cannot be created w/o client contact change message being present.
Case when saga fails:
When i send the the client picture message first it creates a new
saga and stores it.
Then i send a client change message it creates another saga and
stores it i.e does not find the saga created by the client picture
message
Then i send the client contact change message it somehow finds the
saga created by client picture change but now cannot find the staff.
I can't make out why this is happening.
Case when saga succeeds:
When i send the client change message first it creates the saga.
Then i send the client contact change message it finds the saga
and executes fine.
Can anyone please explain why this behaviour is happening.
Please let me know if more information is needed.
Thanks
UPDATE
On checking my code again, i found the cause of this . My ClientChangeMessage was also inheriting from IContainSaga data(something which i was trying out but had forgotten to remove). After removing the inheritance link everything was working fine. (Head hanging in shame)
In all your handlers, you need to set the ClientRef on the Saga Data.
So, you would have:
public void Handle(ClientContactChangeMessage message)
{
Data.ClientRef = message.ClientRef
...
}
As any of these messages can start the saga, you'll need to set this value in your saga state. When other messages come in, then it will be co-rrelated by this id as there is already an instance of the saga with this Id.
To refer to your saga state variables, use Data. intead of this.

WCF - call method from service implementation

What I'm trying to do is the following:
1) I have the following WCF service contract:
[ServiceContract]
public interface IUploadService
{
[OperationContract]
ServiceData Upload(Request request);
}
[DataContract]
public class Request
{
[DataMember]
public long AbnNumber;
[DataMember]
public string Email;
}
2) This contract is implemented like this.
public class UploadService : IUploadService
{
public bool Upload(Request request)
{
// Some code
}
}
In the "Some code" section I would like to call a validation class to validate the clients request, so something like this:
var result = validation.ValidateRequest(request);
So my question is: Is it a bad idea to create an instance of my validation class inside the Upload method? Like this:
public class UploadService : IUploadService
{
public bool Upload(Request request)
{
var validation = new Validation();
var result = validation.ValidateRequest(request);
}
}
I know you can get around this by creating a constructor but as far as I know you can't create a constructor inside a WCF service implementation class, or am I wrong?
I'm new to WCF so if I'm totally heading the wrong direction please let me know.
Thanks
Personally I like as little as possible in my service methods. I would have a separate project to handle the Upload. This then allows you to reuse this code more easily, and to test the functionality without creating the service.
As to whether you should create your Validation like this it really depends on what it does, but generally I would make sure the Validation class implements an interface containing ValidateRequest(Request) and then inject that. You can then mock it in your tests if you need to.
So your service code would look like
public class UploadService : IUploadService
{
private readonly IUploadHandler _uploadHandler;
public UploadService(IUploadHandler uploadHandler)
{
_uploadHandler = uploadHandler;
}
public bool Upload(Request request)
{
//would possibly do some mapping here to create a different type of object to pass to the handler
_uploadHandler.Upload(request);
}
}
and the handler in a different project would look like
public class UploadHandler : IUploadHandler
{
private readonly IValidation _validator;
public UploadHandler(IValidation validator)
{
_validator = validator;
}
public bool Upload(Request request)
{
return _validator.ValidateRequest(request);
}
}
So my question is: Is it a bad idea to create an instance of my validation class inside the Upload method?
It comes down to whether you will be using Singleton or Per Call services. Usually it is better to have new instance of Service created for every request, and in that case it is OK to create all instances in your operation.
Interesting discussion on this topic Should WCF service typically be singleton or not?
If you decide to not to create Validation class for each then request there are two options:
Make it singleton
Create custom ServiceHostFactory for your service and initialize your Service in it (with constructor). Useful links on this topic:Extending Hosting Using ServiceHostFactory, Integrating StructureMap with WCF

Passing List<T> as parameter to WCF service operation

I have a WCF operation contract which looks like this:
public void SavePersons(List<Person> list, bool IsSelected)
{
}
I am passing it a strongly typed list of Person objects (List<Person>) in my client. However, I am getting a bad request 400 message when calling the service. What am I doing wrong?
May I suggest you create you create a contract to encapsulate the parameters like so:
public void SavePersons(PersonCollectionContract Request)
{
...
}
[DataContract]
public class PersonCollectionContract
{
[DataContract]
public List<Person> People { get; set; }
[DataContract]
public bool IsSelected { get; set; }
}
[DataContract]
public class Person
{
...
}
I was facing a similar problem in passing a List<Health> of class Health type as a parameter to a wcf service method. I created a data contract in wcf service as below:
[DataContract]
public class Health
{
...
}
Defined a method in wcf service class such as:
public string GetData(List<Health> healthValues)
In my client application, while configuring/updating the service, I followed these steps:
Add/Update URL
Under Data Type (in Advanced), selected option, Collection type: System.Collection.Generic.List
And finally, I created a list and added the code in client as follows:
List<WcfService.Health> listHealth = new List<WcfService.Health>();
WcfService.Health h = new WcfService.Health();
.
.
listHealth.Add(h);
WcfService.Service1Client s = new WcfService.Service1Client();
string str = s.GetData(listHealth);
This solved my purpose and I was able to send the data as a list through wcf service.

Are NServiceBus handler's members safe for storing message related (and not related) data?

Are handlers reused to proceed another message?
public abstract class SomeHandler : IHandleMessages<MyEvent>
{
public IBus Bus { get; set; }
public String Message { get; set; }
public void Handle(T message)
{
Message = "Test";
SomeInstanceMethod();
}
public void SomeInstanceMethod()
{
if (Message = ...) // Can i use Message here?
return;
}
}
By default, message handlers are configured as ComponentCallModelEnum.Singlecall, which means that each call on the component will be performed on a new instance.
So, two messages will be processed by different instances of the class and cannot share state.
However, what you have here is setting a class property and then calling another method in the class that retrieves that property. That would work fine. However, in my opinion, that is kind of confusing, and if that is what you're after, you're probably better off passing values to another method as a parameter.