WCF - Generalizing Action String - c#

I have to take some pre-defined WSDL's (I do not control these), and expose them on our device to reply to various SOAP/UPnP requests.
Anyway, I have all of this working, but the problem comes through because I have one service that could be requested on any number of channels. I'll explain:
[System.ServiceModel.ServiceContractAttribute(Namespace="urn:some:namespace:1", ConfigurationName="myInterface")]
public interface myInterface
{
[System.ServiceModel.OperationContractAttribute(Action="urn:some:namespace:1#GetConfiguration", ReplyAction="*")]
[System.ServiceModel.XmlSerializerFormatAttribute()]
[return: System.ServiceModel.MessageParameterAttribute(Name="config")]
MyConfigurationResponse GetConfiguration(MyConfigurationRequest request);
}
Basically, what I'm attempting to do (I realize this syntax is completely wrong but I think it will get the point across) is this:
[System.ServiceModel.ServiceContractAttribute(Namespace="urn:some:namespace:{channelNumber}", ConfigurationName="myInterface")]
public interface myInterface
{
[System.ServiceModel.OperationContractAttribute(Action="urn:some:namespace:{channelNumber}#GetConfiguration", ReplyAction="*")]
[System.ServiceModel.XmlSerializerFormatAttribute()]
[return: System.ServiceModel.MessageParameterAttribute(Name="config")]
MyConfigurationResponse GetConfiguration(MyConfigurationRequest request, String channelNumber);
}
I simply would like some portion of my original Action message passed in as a parameter to the method I'm implementing.
The only other way I have thought of that I could implement this, would be to specify some other method, we'll call it Dispatcher with the Action="*", and then manually parse the received action using OperationContext.Current.IncomingMessageHeaders.Action. This just seems like a really shady way of doing things. I'm certain that the main roadblock here is my inexperience with WCF.
Any help you're able to provide would be much appreciated.
Thanks,

The easiest way to manage this is to create a generic message handler. The contract would look something like this:
[ServiceContract(SessionMode = SessionMode.Allowed)]
public interface ICatchAll
{
[OperationContract(IsOneWay = false, Action = "*", ReplyAction = "*")]
Message ProcessMessage(Message message);
}
The idea is that you create a "router" method for your service along the lines of this article. You'll still need to create the individual channel service contracts to shape the soap message to be received & returned but you'll have the client endpoint go to your "router" service endpoint. You may be able to do something along these lines with the new WCF 4 RoutingService if you create a separate instance of each channel service contract.

The only generalization of action method is the wild card * and it is usually used with both input and output as generic Message.
There is a way to customize whole behavior of the operation selection and parameters definition and filling. You can check following interfaces:
IDispatchOperationSelector is used to select operation based on incomming data
IOperationInvoker is used to allocate parameters and invoke the operation selected by IDispatchOperationSelector
IDispatchMessageFormatter is used to fill parameters for the operation to allocation slots prepared by IOperationInvoker
You probably don't need to implement them all but they will allow you to customize the behavior in any way you need. For example of custom selector and formatter check MSDN samples for example of custom invoker check this article. Anyway this whole infrastructure coding will just move your Action parsing to some WCF internals but you will still have to do that to get it as operation parameter.

Related

ServiceStack using interface as template in IReturn<T>

I have a question about IReturn.
I found out that
"Interfaces are most definitely not a perfect valid way to define service interfaces".
But what if despite of that there is a need or idea of doing that.
Is there any way to do that without getting an exception about creating abstract class?
What you've quoted likely refers to WCF's approach of using Interfaces to define Services. WCF promotes several service anti-patterns but this quote has absolutely nothing to do with ServiceStack's IReturn<T> interface marker which is a benign interface whose sole purpose is to enable a succinct typed API without having to define the return type on the call-site, e.g:
CustomerResponse response = client.Get(new GetCustomer { Id = 1 });
If the Request DTO didn't have the IReturn<T> marker then every client would need to define the return type on the call-site, e.g:
CustomerResponse response = client.Get<CustomerResponse>(new GetCustomer { Id = 1 });
Which is unnecessary and a potential source of human error since clients would need to provide the correct response type for each Services whereas if the return type was only defined once on the server (i.e. the authoritative source) then all clients would automatically use the correct response Type since it's embedded on the Request DTO contract - the correct place for it since it defines part of your public Service Contract.
There is no good reason why you wouldn't include an IReturn<T> marker, the only valid reason you wouldn't was if your Service returned multiple different Response Types, but that is of itself an anti-pattern and a source of errors that's only detectable at runtime, i.e. the worst kind.

Order of multiple IOperationInvoker on the same operation

Is there any built-in possibility to tell WCF exact order in which I want my custom operation invokers to be executed?
Some background: I have several custom operation invokers in WCF and each of them performs one task, like:
Set active user
Check for access rights
Set culture information
etc.
Order is very important, because I need first determine user and only then check rights.
Is there any built-in possibility to tell WCF exact order?
No. There’s no WCF interface to for that.
Can you control the order through configuration?
Yes. The order of execution of the different IOperationInvoker’s is predictable and controllable through configuration. You could use this to meet your requirements.
IOperationInvoker Background
Carlos Figueira’s blog: WCF Extensibility – IOperationInvoker gives an example of a custom invoker. Probably too much information, but it shows how multiple invokers chain together and how they are configured and applied to the operation through a WCF behavior.
My point is: OperationInvoker's are interceptors. Each time a new invoker is added to the operation, the previous one is stored.
In other words from the example the behavior that applies the invoker looks like this:
public class CacheableOperationAttribute : Attribute, IOperationBehavior
{
// omitting lots of code...
public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
{
dispatchOperation.Invoker = new CachingOperationInvoker(dispatchOperation.Invoker, this.secondsToCache);
}
}
And the invoker stores the previous invoker:
public class CachingOperationInvoker : IOperationInvoker
{
// omitting lots of code...
public CachingOperationInvoker(IOperationInvoker originalInvoker, double cacheDuration)
{
this.originalInvoker = originalInvoker;
this.cacheDuration = cacheDuration;
}
}
Then the invoker method looks like this:
public object Invoke(object instance, object[] inputs, out object[] outputs)
{
// do this invokers work before others?...
// at some point call the next invoker
object result = this.originalInvoker.Invoke(instance, inputs, out outputs);
// do this invokers work after others?...
return result;
}
}
Note: You need to know the invoker implementation (when it calls the next invoker in the stack) to fully understand how multiple invokers sequence. There's no rules or conventions on this (for good reason).
Configuration
WCF behaviors can be added to an operation in a couple different places: code, config file, etc. So many options can cause confusion (bugs) for your use case.
If your OperationInvokers are tightly coupled, my suggestion would be to create a single custom behavior that adds all the IOperationInvokers in the right order.
So while you can't "tell" WCF the execution order, you can predictably control it.

How does __TransparentProxy work?

When using WCF, we can define a service contract:
[ServiceContract]
public interface IMyService
{
[OperationContract]
int MyOperation(int x);
}
Assume I open a servicehost at www.example.com/MyService, then one way to use this service from my client is
IMyService service =
new ChannelFactory<IMyService>(new BasicHttpBinding(),
new EndpointAddress("www.example.com/MyService")).CreateChannel();
int result = service.MyOperation(10);
So somehow, service implements IMyService, although that was never done explicitly. If I debug these lines, I can see that service is an instance of __TransparentProxy. As you can see from the source code, the comments in that class say
Transparent proxy magically creates a message that represents a call on it and delegates to the Real proxy to do the real remoting work.
To me this is indeed 'magic', but I guess there must be a logical explanation.
The pattern here can be very useful. What I would like is some class like Magic below (the syntax is incorrect, I know, otherwise I wouldn't need to ask). For the sake of argument, let's say I want this class to print the name of the method called.
public class Magic<T> : T {
// don't know what to do here
}
Such that I would be able to call
IMyService service = new Magic<IMyService>();
service.MyOperation(10);
And this would print:
MyOperation
Is something like this possible? (It should be, since __TransparentProxy does something similar.) And if so, how would this work?
There are a few articles on Codeplex that try to do something similar to what WCF does under the covers:
http://www.codeproject.com/Articles/43598/Emit-Proxy
http://www.codeproject.com/Articles/5511/Dynamic-Proxy-Creation-Using-C-Emit
The System.Reflection.Emit namespace is the underlying key, which can be used to dynamically create .NET assemblies and types in code.
Any one else running across this answer might want to look at Aspect Oriented Programming (AOP) in general
And possibly PostSharp specifically: https://www.postsharp.net/aop.net

Flexible Logging interface design in C#

I want to write my own Logging classes (in C#) which implement a standard interface, which I can call from any part of the code.
My idea is to have multiple Log classes implement the Logger interface, each for its specific log destination, for example, a FileLogger will implement logging to a file, a TextBox logger will implement logging into a Multi Line TextBox in a Form, a DBLogger will implement logging to a database table, etc.
Further, each logger class can have a nested logger or chained logger classes, so that a single call to Log() method from the application code can log the message in multiple destinations; example log to a file and a textbox on Form in a single call.
The difficulty I am facing is this:
Usually I log to a running log file (which will contain all log messages required for debugging), a review log file (which will contain only log messages to be reviewed by the user, or which require user action), a Multi Line textbox on screen (which will replicate all log messages to give a progress indication to the user), and another Multi Line textbox (which will log only messages required for user to review).
When I call logger.Log(message), some messages may not apply to a particular log destination. For example, some message may be intended to be logged only in a running log file or progress textbox, but not in the user review textbox, and vice versa.
Since the loggers will be chained so that a single function call can log into all required destinations, how can a particular logger identify that the log message is not intended for it and hence ignore the log message?
My sample log interface is:
public interface Logger
{
public void Log(string msg);
public void Log(string msgType, string msg);
public void InitLogSession();
public void EndLogSession();
public void AddLogger(Logger chainedLogger);
public void RemoveLogger(Logger chainedLogger);
}
public class FileLogger : Logger
{
//implement methods
}
public class TextBoxLogger : Logger
{
//implement methods
}
public class DBLogger : Logger
{
//implement methods
}
EDIT 1:
To be more precise, there could be 4 loggers: 2 file loggers and 2 textbox loggers. A particular message is suppose meant for 1 of the textbox loggers, and 1 of the file loggers; how should my design handle this?
EDIT 2:
Please do not suggest existing logging frameworks. I just want to write it on my own !
EDIT 3:
Ok. I have a design. Please give your feedback and probably fill the gaps.
The revised interface:
public interface Logger
{
public void Log(string msg);
public void Log(string msgType, string msg);
public void Log(int loggerIds, string msg);
public void Log(int loggerIds, string msgType, string msg);
public void InitLogSession();
public void EndLogSession();
public int getLoggerId();
}
public enum LoggerType
{
File,
TextBox
};
public class LoggerFactory
{
public Logger getLogger(LoggerType loggerType)
{
}
}
The LoggerFactory class will be the sole way to instantiate a logger. This class will assign a unique id to each instance of a logger. This unique id will be a power of 2. Example, 1st logger will get id 1, 2nd will get id 2, 3rd will get 4, and 4th will get 8, and so on.
The returned logger object can be typecast to specific class, and further values like filePath, textbox, etc. can be set by the caller, or else I can have multiple methods in LoggerFactory: one for each type of logger, which will accept specific parameters.
So, suppose we have 4 loggers with ids 1,2,4,8.
A particular message which has to be processed by the 1st and 3rd logger (i.e. logger ids 1 and 4) has to be logged using the function:
public void Log(int loggerIds, string msg);
The value to be passed to loggerIds should be "0101". Each logger will check whether its logger id bit is ON. If yes, only then it will log the message.
Now in the function signatures, I have mentioned int type, but which is the specific optimised type for performing bit manipuations and comparisons?
In this approach, there can probably be a limit on the max no. of loggers, but that is fine with me. Please give your feedback.
Note: Currently I am still on .NET 2.0. If possible, suggest solution within .NET 2.0, else fine, I can move to higher versions.
CONS of this design: Each class which needs to log, needs to know about all the available loggers instantiated by the application, and accordingly set up the bit pattern. Any ideas how to have a loosely coupled design?
Why don't you look at (or indeed use) an existing logging framework such as log4net or NLog.
They have the concept of a log level (e.g. trace, info, error etc) as well as being able to filter by the name of the log (which is normally the fully qualified type name which invoked the logging call). You can then map these to one or more 'targets'.
"Please do not suggest existing logging frameworks. I just want to write it on my own !"
Accepted answer: Don't reinvent the wheel! Use this existing logging framework!
facepalm
The best answer, which is my answer, goes something like this.
Use interfaces if you want plug and play functionality. You can make it easily configurable. Here's the high level run down.
Use a config file to indicate what type of logger you want
which implements your logging interface
Use reflection to instantiate the type you pull from
your config file AT RUNTIME.
Pass in your logger interface you just made via constructor injection inside your classes.
You're not reinventing the wheel by designing by interface.
If you make your interface general enough, it is implementation non specific (ideally).
This means if log4net goes to crap, or is no longer supported, you don't have to RIP OUT AND MODIFY ALL YOUR CALLING CODE. This is like hard-wiring a lamp directly into your house to turn it on. For the love of god, please don't do that.
The interface defines the contract by which the components interact, not the implementation.
The only thing I can think of is, look at existing logging frameworks, find the common elements, and write your interface as the intersection of the common features. Obviously there are going to be features that you miss. It depends on how much flexibility you want. You can use Log4net, or the Microsoft Event Viewer logger, or both! No implementation details are re implemented. And it is a MUCH less coupled system than having everything in your code tied to one technology / framework.
As devdigital wrote, these Frameworks usually do this by providing designated methods for Logging like: Warn("..."), Fail("...")...
You could also look for the ILogger interface of the logging facility of the castle project. (maybe try to google the ILogger.cs sourcecode)
If you still adhere to your approach of chained loggers with common interface (for which you you would also have to implement a chaining mechanism) you would have to provide a kind of logging level to your Log() method. This may be just an integer or an enum as well.
Like this:
public interface Logger
{
public void Log(LogLevel level, string msg);
public void Log(LogLevel level, string msgType, string msg);
public void InitLogSession();
public void EndLogSession();
public void AddLogger(Logger chainedLogger);
public void RemoveLogger(Logger chainedLogger);
}
With an logging level enum like this:
public enum LogLevel
{
Info,
Warn,
Debug,
Error,
Fail
}
The loggers to use would then be selected within a chain of responsibility.
I wrote my own logger some time ago. To be honest it was not as good as those available for free and I realized that I was trying to re-invent a wheel that was already round!
I see that you want to write your own code but it might still be an idea to look at open source solutions and perhaps use them or modify them for your own specific needs
I now use TracerX: http://www.codeproject.com/Articles/23424/TracerX-Logger-and-Viewer-for-NET This is an open source project so it easy to modify the source code it you need to. The other loggers mentioned are also good of course.
EDIT
This is based on the accepted answer to my question here: How to pass status information to the GUI in a loosely coupled application So I claim no originality in this. Your log messages are simple at the moment I think
My suggested answer is that you use a message type that can process (e.g.) send itself to different loggers based on either some logic passed to it at run time or by using a factory to create different message types depending on run time conditions.
So
create an abstract message class or interface that has a process method.
create a number of message types inheriting from the abstract class or interface that represent the different types of logging you want to carry out. The process method could determine where to send them.
Consider using a factory to create the message type you need during runtime so you don't need to decide what types you will need in advance
When you generate a log message use the process message to route the message to the loggers you want it to go to
This seem like a good place to use extension methods.
Create your base class, then create the extension methods for it.
BaseLogger(LogMessage).toTextBoxLog().toFileLog().toDatabaseLog().
This way, you always call the BaseLogger and then only the extension methods where needed.
.NET now provides the ILogger interface which can be used with a variety of .NET or 3rd party logging tools through dependency injection.
Using this you can separate your logging functionality in code, from the concrete implementation in your architecture, and can later swap out loggers without significant modification to your business code.
https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.logging.ilogger?view=dotnet-plat-ext-6.0
https://learn.microsoft.com/en-us/dotnet/core/extensions/logging?tabs=command-line

Number of classes under one proxyClient in wcf

I want to know is it possible to create one wcf proxy client that have separated classes that hold number of methods ?
Meaning for example :
SomeClient _client = new SomeClient();
_client.Class1.SomeMethod();
_client.Class2.SomeMethod();
all of that in the same service and interface ?
in all what i want is to group the method under one class with distinc name and in one service.
Thanks
Guy
You're not going to be able to do this with a ServiceReference WCF Proxy, no. It just doesn't generate the proxies that way.
You could wrap the proxy in classes that pass the methods you want to the proxy but otherwise do nothing.
Another option, if you have control over the service itself, is to separate the methods into separate services. Given your apparent desire to have separation of concerns, this may be a good option to pursue.
could you explain alittle bit more on the second part of your answer please. with example
There are multiple ways to accomplish this. This example is incomplete and doesn't feature important error handling and proxy instantiation. I'll leave that for you.
public class Svc1
{
private Proxy proxy;
public void Method1(string param)
{
Proxy.Method1(param);
}
}
public class Svc2
{
private Proxy proxy;
public int Method2()
{
return Proxy.Method2();
}
}
public class MegaProxy
{
public Svc1 Class1 {get; set;}
public Svc2 Class2 {get; set;}
}
i dont want the programmer of the client side use many services, you know just writing all of the using statement is confusing, i want to give it to him plan and simple under one proxy
Hmm... I see some unfortunate assumptions in your statement here. I'm guessing you're relatively new to WCF, and that's fine, but that means you haven't run into this problem yet: Never, ever use using on a WCF proxy. The reason is that the Dispose method of WCF proxies can throw in certain circumstances -- primarily f the service call faulted. This can lead to some surprisingly ugly problems if you're not aware of the issue. It's almost always best to use an Open Proxy => Call Service => Close Proxy paradigm instead.
That said, I don't think it would be too different for your client to call separate services than to call methods on separate fields of a single proxy. If anything, separate services would allow your client better control over when and how a proxy is created.
If you have control over the client code -- if you're providing the proxy itself as a .DLL, for example -- you could build a static class with static methods that instantiate the different proxies for the client.

Categories