How to access static member on WCF service? - c#

i want to access static member which is located in WCF service.
public class PDFService : IPDFService
{
public string CreatePDF()
{ //some code
}
private static event EventHandler MyPrivateEvent;
public static event EventHandler MyEvent
{
add { MyPrivateEvent += value; }
remove { MyPrivateEvent -= value; }
}
}
I tried to access this MyEvent member from a Windows Store app, but it doesnt work.
I want to accomplish something like this (similar to example from msdn):
PDFServiceClient proxy = new PDFServiceClient();
//Wire the proxy to a completed handler to allow the async operation to be handled
proxy.MyEvent += new EventHandler<CreatePDFCompletedEventArgs>(
proxy_CreatePDFCompleted);
//Call the service asynchronously
await proxy.CreatePDFAsync();

Events are not exposed to the consumer of a WCF service. Neither are static members at all. The only things exposed are the operations in the service contracts, and any types used by those operations.

Related

Event dispatching library with IoC

In the past I've built a MessageDispatcher component that scans an assembly for types decorated with certain attributes and initializes an instance of each. Then, when any object is fed to the MessageDispatcher instance, every previously initialized instance which contains a method which signature contains the type of the passed object has said method triggered with the specified parameter. For example, in a scenario like:
[Listener]
public class MyListener
{
MessageDispatcher _dispatcher; //Assigned elsewhere
[MessageListener]
public async Task DoSomething(int value)
{
var otherValue = await _dispatcher.Next<string>();
Console.WriteLine($"{value} is {otherValue}.");
}
}
The following code initializes an instance of the MyListener class, calls DoSomething and prints "7 is okay.":
var listener = new MessageDispatcher(typeof (ListenerAttribute));
listener.Dispatch(7);
listener.Dispatch("okay");
I would like to know if there are any libraries out there that are dedicated to or include a service like such. It has to be able to:
Scan assemblies and initialize types based on an attribute.
Dynamically "subscribe" to certain types
"Wait" on a value to be pumped from the dispatcher (like with the Next method in my example).
(as library recommendations is not allowed per the SO rules, here is an attempt to instead answer with an implementation)
You can get that with virtually any IoC. All they need is to be able to register services using an attribute or some other conventional way.
As for the message dispatching. Just create an interface like IMessageHandler<TMessage>. Implement it on all classes that should handle messages.
Example:
public interface IMessageHandler<TMessage>
{
void Handle(TMessage msg);
}
public class SomeService : IMessageHandler<UserCreated>
{
//[.. all other methods ..]
public void Handle(UserCreated msg)
{
// ...
}
}
To publish messages you create a dispatcher. Since you use a container you do not have to make it static. Use your container inside it (service location) to dispatch the messages. Now some peeps might say oohh no, service location is anti-pattern, buhuhuhu. Well no. Not in all cases. In this case it's an implementation details in a class with the specific purpose to identify and invoke other classes.
public interface IMessageDispatcher
{
void Dispatch<TMessage>(TMessage msg);
}
// The actual implementation differs
// depending on your choice of container.
public class ContainerBasedMessageDispatcher : IMessageDispatcher
{
Container _container;
public ContainerBasedMessageDispatcher(Container container)
{
_container = container;
}
public void Dispatch<TMessage>(TMessage message)
{
using (var scope = container.BeginLifetimeScope())
{
var handlers = scope.Resolve<IEnumerable<IMessageHandler<TMessage>>();
foreach (var handler in handlers)
{
handler.Handle(message);
}
}
}
}
The code is written directly in SO. So it might not work as-is. But hopefully it's given you an idea how to achieve what you want.
Usage:
public class UserService
{
IMessageDispatcher _dispatcher;
public UserService(IMessageDispatcher dispatcher)
{
_dispatcher = dispatcher;
}
public void Create(User user)
{
//[...]
_dispatcher.Dispatch(new UserCreated(user.Id));
}
}
this do however not dynamically allow you to subscribe on what you want. If just ignoring unwanted messages is not feasible. Then this answer is not for you.

Where to register domain event handlers in c# class library DLL

I have a solution set up like so:
Solution
Visual Basic ASP.NET Web Application (.NET4)
C# Class Library (.NET2)
The class library DLL is included as a reference in the web application.
The class library makes extensive use of domain driven architecture. Now, I'm in the process of adding domain events, in the way of Udi Dahan.
public static class DomainEvents
{
[ThreadStatic] //so that each thread has its own callbacks
private static List<Delegate> actions;
public static IContainer Container { get; set; } //as before
//Registers a callback for the given domain event
public static void Register<T>(Action<T> callback) where T : IDomainEvent
{
if (actions == null)
actions = new List<Delegate>();
actions.Add(callback);
}
//Clears callbacks passed to Register on the current thread
public static void ClearCallbacks ()
{
actions = null;
}
//Raises the given domain event
public static void Raise<T>(T args) where T : IDomainEvent
{
if (Container != null)
foreach(var handler in Container.ResolveAll<Handles<T>>())
handler.Handle(args);
if (actions != null)
foreach (var action in actions)
if (action is Action<T>)
((Action<T>)action)(args);
}
}
I need to register my domain event handlers in the class library. There is no global.asax for a class library, so I cannot make use of Application_Start. Where is the best place to register domain event handlers in a class library?
Your application is responsible for glueing everything together.
You either hook everything up on Application_Start or you invoke a function in the class library from there that registers your handlers.
new Bootstrapper().Bootstrap();

C# How to create a Singleton that publishes events & Classes that subscribe?

Goal: Have a singleton publish events and allow any class to subscribe/listen to those events
Problem: I cannot figure out how to do this. The code below is illegal but it purveys what I'm trying to do
TransmitManager Class - Publisher
//Singleton
public sealed class TransmitManager
{
delegate void TransmitManagerEventHandler(object sender);
public static event TransmitManagerEventHandler OnTrafficSendingActive;
public static event TransmitManagerEventHandler OnTrafficSendingInactive;
private static TransmitManager instance = new TransmitManager();
//Singleton
private TransmitManager()
{
}
public static TransmitManager getInstance()
{
return instance;
}
public void Send()
{
//Invoke Event
if (OnTrafficSendingActive != null)
OnTrafficSendingActive(this);
//Code connects & sends data
//Invoke idle event
if (OnTrafficSendingInactive != null)
OnTrafficSendingInactive(this);
}
}
Test Class - Event Subscriber
public class Test
{
TrasnmitManager tm = TransmitManager.getInstance();
public Test()
{
//I can't do this below. What should my access level be to able to do this??
tm.OnTrafficSendingActive += new TransmitManagerEventHandler(sendActiveMethod);
}
public void sendActiveMethod(object sender)
{
//do stuff to notify Test class a "send" event happend
}
}
You shouldn't need to make the events static.
public event TransmitManagerEventHandler OnTrafficSendingActive;
public event TransmitManagerEventHandler OnTrafficSendingInactive;
Either your events have to be instance members or you have to address them as static.
TransmitManager.OnTrafficSendingActive +=...
OR
public event TransmitManagerEventHandler OnTrafficSendingActive;
...
TransmitManager.Instance.OnTrafficSendingActive+=...
Also: use EventHandler as your event delegate. Consider making a custom arguments class and pass the status to just one event instead of multiple events. This will let you pass status messages as well.

Event-delegate analogy in WCF

I have WinForms app with MVC pattern implemented, where Model is running asynchronously (backgroundWorker thread) from View (Form). View is subscribed to couple of events that are raised from Model.
Now I need to convert this to WCF app, where event-eventHandler concept has to be present.
At first, I wanted to implement this via callback interface, but in my case one method from Model is raising more than one type of events, and I am constrained on usage of single callback interface when defining service contract.
At this moment I came up with the idea of specifying different type of events as methods in callback service and implement it in client. For example:
public interface ICallbacks
{
[OperationContract(IsOneWay = true)]
void EventHandler1();
[OperationContract(IsOneWay = true)]
void EventHandler2(string callbackValue);
[OperationContract(IsOneWay = true)]
void EventHandler3(string callbackValue);
}
Should I go along with this solution or there are some better alternatives (publish-subscribe wcf pattern)?
Sounds like you definitely want pub/sub architecture here.
Take a look at Juval Lowy's Publish-Subscribe Framework from this MSDN article:
http://msdn.microsoft.com/en-us/magazine/cc163537.aspx
You can use single method with a base type parameter to activate your call. Then in your service code, jump to specific handler based on the type of the event.
public class BaseEvent { }
public class MyFirstEvent : BaseEvent { }
public class MySecondEvent : BaseEvent { }
public class MyThirdEvent : BaseEvent { }
public interface ICallbacks
{
[OperationContract(IsOneWay = true)]
void EventHandler(BaseEvent myEvent);
}
public class MyService : ICallbacks
{
public void EventHandler(BaseEvent myEvent)
{
//Now you can check for the concrete type of myEvent and jump to specific method.
//e.g.:
if (myEvent is MyFirstEvent)
{
//Call your handler here.
}
//Another approach can be predefined dictionary map of your event handlers
//You want to define this as static map in class scope,
//not necessarily within this method.
Dictionary<Type, string> map = new Dictionary<Type, string>()
{
{ typeof(MyFirstEvent), "MyFirstEventHandlerMethod" },
{ typeof(MySecondEvent), "MySecondEventHandlerMethod" }
{ typeof(MyThridEvent), "MyThirdEventHandlerMethod" }
};
//Get method name from the map and invoke it.
var targetMethod = map[myEvent.GetType()];
this.GetType().GetMethod(targetMethod).Invoke(myEvent);
}
}
Using a Duplex is not a good idea unless your application runs on the same at least on the same network and there are not proxies, etc to interferer with. You will also end up with a tight coupling between publisher and subscriber.

Properway to encapsulate Asynchronous Web Service Communications

I usually try to encapsulate my web service calls in my client side apps.
Rather than doing this:
public Guid FindUserIDSelected(string userName)
{
MyWebServiceReference service = new MyWebServiceReference(GetEndpointBasedOnEnv(Env));
return service.GetUserIDFromName(userName);
}
I have a static class that encapsulates the communication with the web services. It handles the endpoint resolution via determining the environment (and other such things).
So the above code changes to look like this:
public Guid FindUserIDSelected(string userName)
{
return Communication.GetUserIDFromName(userName);
}
But now I am having an issue. Silverlight only supports Asynchronous calls (at least as far as I am seeing). So calling a web service and then returning the value in an encapsulated call does not work.
The best I can come up with is passing in a delegate that is used in the Communication class for the completed event:
private Guid foundUserID;
public void FindUserIDSelected(string userName)
{
Communication.GetUserIDFromName(userName, GetUserIDCompleted);
}
private void QuestionRecieved(object sender, GetUserIDFromNameCompletedEventArgs e)
{
foundUserID= e.Result();
}
This has several problems (in my opinion).
I now have elements of the web services that have broken encapsulation (the completed call is really the web service return. I don't want the rest of my classes to have to care about the services).
I have had to expose my result (foundUserID) at the class level.
Am I being too rigid? Is that good enough? Is there a better way?
Am I the only one who has this issue?
In my opinion, it'd better to use eventing from your communication class, especially if you have some thing like [EventAggregator]1, so you can filter an event based on your specific argument
Below is the code snippet, this may be helpful for you.
public static class Communication
{
public static event EventHandler<MyEventArgs> ServiceCallComplete;
public static void InvokeMyAcionComplete(MyEventArgs e)
{
EventHandler<MyEventArgs> handler = ServiceCallComplete;
if (handler != null) handler(null, e);
}
public static void CallService ()
{
//Performed async call
// Fire the event to notify listeners
OnServiceCalled();
}
private static void OnServiceCalled ()
{
InvokeMyAcionComplete(new MyEventArgs());
}
}
public class ClientCode
{
public void CallService()
{
Communication.CallService();
//Subscribe to the event and get notified when the call is complete
Communication.ServiceCallComplete += OnServiceCalled;
}
private void OnServiceCalled(object sender, MyEventArgs e)
{
//MyEventArgs is your customized event argument
//Do something with the result
}
}
Hope this help

Categories

Resources