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
Related
To clarify my question, suppose I have the following very basic statistics interface and class:
public interface IStatistics
{
void IncrementPacketsDiscovered();
}
public class Statistics : IStatistics
{
private int numberOfPacketsDiscovered = 0;
public void IncrementPacketsDiscovered()
{
numberOfPacketsDiscovered++;
}
}
Then suppose I have the following class that receives the injected IStatistics object:
public class Reporter
{
private IStatistics _statistics;
public Reporter(IStatistics statistics)
{
_statistics = statistics;
_statistics.IncrementPacketsDiscovered();
}
}
Why is it that I am able to call the IStatistics method IncrementPacketsDiscovered() on the IStatistics object and it automatically knows to fetch the method definition that was implemented in the Statistics class?
Any help would be greatly appreciated. Thank you!
TLDR; because the injected object that implements IStatistics is an instance of the Statistics class, and it is this way because somewhere else you told the dependency resolver to use Statistics whenever you mention IStatistics..
Note that Statistics.IncrementPacketsDiscovered being called is nothing to do with DI per se, you could write this:
IStatistics x = new Statistics();
x.IncrementPacketsDiscovered();
On the outside, x looks like an IStatistics. On the inside, it is a Statistics. If Statistics did something else (other than just implement the interface) it would be easier to see. It would also probably be more clear what's going on if you had something else that implemented IStatistics, like some sort of FakeStatistics that you use in a test scenario - testing is one such valid reason where you'd switch your program back and forth between different suites of objects.
You could just conceive that somewhere outside of all your code is the dependency resolver, a thing created by Microsoft*. It did that first line of code above for you, and later when you said you wanted to have a Reporter it looked and saw "the constructor takes a parameter of anything that implements IStatistics, and I just happen to have an instance of Statistics here that fits that requirement, so I'll pass that into the Reporter constructor.." because that is what it is configured to do/that is its job.
If you had a FakeStatistics that you used for testing, and a context where you reconfigured the injector to create and supply fake objects then it suddenly starts to make sense why it's a useful way to engineer - you don't have to have 100 places where you said new Statistics where you go through and change them all to say new FakeStatistics. It's also useful to be writing a class and suddenly realize "this class needs statistics.." you add a single argument IStatistics x to the constructor, hit Ctrl . and pick the option to add a property for it and that class now has access to a suitable implementation of IStatistics, supplied by the resolver. You don't have to chase up through everywhere you said new MyXClass(param1, param2) and change it to say new MyXClass(param1, param2, someStatistics) because the job of newing all your objects is the responsibility of the resolver
By using interfaces and coding up such that "any object that implements this interface can sensibly be used as an input argument to this class" you then open it up to the possibility that a "class instance lookup and provider service" can wire all your app together just by "rummaging around in its currently configured bag of objects for one that will do the job" (and then you change what's in the bag depending on the context)
So where did you put things in the bag? In the part of the program where you configured the resolver, methods like AddScoped, AddTransient, AddSingleton have the dual purpose of mapping a type of class to a type of interface and also configure what sort of lifetime the instance has- resolvers manage instances for you and create/destroy them over the lifetime you specify by which Add* method you use
* With this statement I am, of course, making a gross assumption as to which injector you're using. There are other DI/IoC frameworks available for C#, created by others. The overarching concept remains the same; the more you can get the computer to write your code for you, the quicker, easier and more reliable it can be. Establishing dependenceies between objects in your program is one such place where it can make sense to hand it off to software rather than writing it yourself
I've built a reusable Class Library to encapsulate my Authentication logic. I want to be able to reuse the compiled *.dll across multiple projects.
What I've got works. But, something about how I'm making the reference, or how my Class Library is structured isn't quite right. And I need your help to figure out what I'm doing-wrong/not-understanding...
I've got a Class Library (Authentication.dll) which is structured like this:
namespace AUTHENTICATION
{
public static class authentication
{
public static Boolean Authenticate(long UserID, long AppID) {...}
//...More Static Methods...//
}
}
In my dependent project I've added a reference to Authentication.dll, and I've added a using directive...
using AUTHENTICATION;
With this structure I can call my Authenticate method, from my dependent project, like so...
authentication.Authenticate(1,1)
I'd like to be able to not have to include that "authentication." before all calls to methods from this Class Library. Is that possible? If so, what changes do I need to make to my Class Library, or how I'm implementing it in my dependent project?
In C# a function cannot exist without a class. So you always need to define something for it, being a class for a static method or an object for an object method.
The only option to achieve that would be to declare a base class in the Authentication assembly from which you inherit in the dependent projects.
You could expose Authenticate as a protected method (or public works too), and call it without specifying the class name.
public class MyClassInDependentProject : authentication
{
public void DoSomething(int userId, long appId)
{
var success = Authenticate(userId, appId);
…
}
}
That said, you'll quickly find this to be a bad design. It conflates a cross-cutting concern with all sorts of other classes, and those classes are now precluded from inheriting from any other class.
Composition is a core principle of object-oriented programming, and we have the idiom "Favor composition over inheritance." This simply means that we break down complexity into manageable chunks (classes, which become instantiated as objects), and then compose those objects together to handle complex processing. So, you have encapsulated some aspect of authentication in your class, and you provide that to other classes compositionally so they can use it for authentication. Thinking about it as an object with which you can do something helps, conceptually.
As an analogy, think about needing to drill a hole in the top of your desk. You bring a drill (object) into your office (class). At that point, it wouldn't make sense to simply say "On," because "On" could be handled by your fan, your lamp, your PC, etc. (other objects in your class). You need to specify, "Drill On."
If you are making a class library in C# you should learn to use the naming conventions that exists: Design Guidelines for Developing Class Libraries
Here is how you should name namespaces: https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/interface
C# is also an object oriented language, hence the need of classes (using Authentication as you should name your class).
It also seems like the data source is hard coded. Your class library users (even if it's just you) might want to configure the data source.
Google about singleton and why it's considered to be an anti pattern today (in most cases).
You are obliged to use Class in order to invoke your method, just
When is static class just NameClass.Method
When is not static, you must create instance, ClassName ob = new ClassName(); ob.Method();
The format of a call like this is class.method, and you really can't escape using the "class" moniker even with the "using" designation. Something has to "host" the function.
I don't think what you are asking for is possible without using the base class method Jay mentioned. If all you want is to simplify the syntax whenever you call Authenticate() however, this silly solution (adding an extra method in each class that needs to do authentication) may be just what you want:
private static void DoAuth(long UserID, long AppID){
authentication.Authenticate(UserID, AppID)
}
If the ID's are always the same within some context, you could also overload it:
private static void DoAuth(){
DoAuth(1,1)
}
Yes, this does mean you have to add more code wherever you want to do the authentication (that's why it's silly! ;) ). It does also however, also reduce this:
authentication.Authenticate(1,1);
...into this:
DoAuth();
I leave the cost / benefit analysis of this up to you..
I know I am some 3 years late but here goes nothing.
To keep your code cleaner and more readable you should create a new namespace for all the re-usable code that you want to have. Then in that namespace have the Authentication Class and Authenticate Function.
To use this you can easily set a using on your namespace and use the function as you are doing like
Authentication.Authenticate()
But to use
Authenticate()
by itself you can always do
using MyNamespace.Authentication;
and in your code use Authenticate Function directly.
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.
So I have some code like this.
[DataContract]
public class Example
{
SomeClass _someVar;
[OnDeserializing]
public void OnDeserializing(StremingContext c)
{
_someVar = new SomeClass();
}
}
Here is the funny thing, OnDeserializing() gets called if I use the test debugging client from Visual Studio 2010. But if I try and host my WCF service and then call it from my own client it doesn't get called (or probably doesn't), because _someVar is always null.
Argh!
What else do I need to do?
Kind regards,
Fugu
WCF does not use standard .net serialization, so I'm not certain it will invoke your OnDeserializing method. However you can ask WCF to use an XmlSerializer, which should give you the behavior you want. Have a look at "Controlling the Serialization Process" here.
Further to PaulF's answer, your class is not a singleton - 2 calls to the service will by default instantiate Example twice and call the method once.
Because of this, there's really very little point in having any variables declared at a class level.
If you want to change this behaviour, have a look here for more information
I am working on a piece of C# web application that has a page (MainPage) with a small area to display a gadget. There are several kinds of gadgets implementing a main interface (IMainInterface) and an optional interface (IOptionalInterface).
In MainPage, when interacting with the gadget class, it uses following syntax:
MyAPI api = new MyAPI();
api.SomeMethod(gadgetClassName, param);
And in api.SomeMethod(...), it does following:
// use reflection to get an IMainInterface based on gadgetClassName
Type t = Type.GetType(gadgetClassName);
IMainInterface gadget = (IMainInterface)t.InvokeMember(
gadgetClassName,
BindingFlags.CreateInstance,
null,
null,
null);
return gadget.SomeMethod(param)
Looking at this MyAPI class, it contains a whole bunch of methods that map to the corresponding methods defined in IMainInterface and IOptionalInterface.
My question, is this MyAPI class really neccesary? Wouldn't it be less overhead if MainPage accesses interfaces(IMainInterface and IOptionalInterface) directly?
Update: seeing some of the answers, I realized that I wasn't explicit that the "several kinds of gadget" means different classes (e.g. CalendarGadget, TaskGadget).
Update 2: Added more code sample
The MyApi class looks like it's shielding you from using reflection to create the object, null checks if the optional interface isn't in use, and probably the whole fact of using interfaces in general. Without all the code it's conjecture. As Dzmitry Huba points out, mixing a factory and a wrapper is a bad smell, and you should try to refactor that out.
static class GadgetFactory
{
public static IMainInterface GetGadget(string className)
{
(IMainInterface)Activator.CreateInstance(Type.GetType(className))
}
}
A factory decouples the logic of creation, but it should only be responsible for creation.
Q: Is there any logic in myAPI, or is it just creating and then dispatching if the gadget supports the interface?
If MyApi doesn't have any logic, it's hard to see why it's necessary. Perhaps the writer of MyApi didn't realize at the time that you can cast to the other interface when needed. I have a hunch that they were trying to shield junior developers from interfaces.
// basic use of interfaces
IMainInterface gadget = GadgetFactory.GetGadget("Gadgets.Calendar");
gadget.SomeMethod();
IOptionalInterface optional = gadget as IOptionalInterface;
if( optional != null ) // if optional is null, the interface is not supported
optional.SomeOptionalMethod();
A relevant SO question Difference between Activator.CreateInstance() and typeof(T).InvokeMember() with BindingFlags.CreateInstance
It seems the author of MyApi mixed factory and consumer. I do not see any reason to access interface members indirectly when it is defined at compile time.
Yes, from the description in your question, I'd say reflection or any other indirection mechanism is unnecessary. I'm not sure if that answers your question though?
// in MainPage:
IList<IMainInterface> gadgets = new List<IMainInterface>
{
(IMainInterface)Activator.CreateInstance(Type.GetType("Gadgets.CalendarGadget")),
(IMainInterface)Activator.CreateInstance(Type.GetType("Gadgets.TaskGadget")),
};
Generally this is not bad. But I guess that this is complete overkill for your intentions. I would suggest to borrow something from IOC.
var api = new MyAPI(new GadgetClass());
api.SomeMethod(parameters);
This would make your life much less complicated.
Hope this helps