Ordering of Postsharp Aspects execution - c#

Ok, this may get lengthy. I am trying to do two things:
I want to have a class that implements an interface by holding an instance of another class that every call is routed to.
I also want to intercept all method calls and do something.
Doing both on their own works great. Combining them seems to work only in one execution order and as Murphy has it, it's the wrong one (at least for me).
I'd like to inject the composition first so that the interception of all calls will also intercept those that were previously injected.
namespace ConsoleApplication13
{
using System;
using System.Reflection;
using PostSharp;
using PostSharp.Aspects;
using PostSharp.Aspects.Dependencies;
using PostSharp.Extensibility;
[Serializable]
[ProvideAspectRole("COMPOSER")]
public sealed class ComposeAspectAttribute : CompositionAspect
{
[NonSerialized]
private readonly Type interfaceType;
private readonly Type implementationType;
public ComposeAspectAttribute(Type interfaceType, Type implementationType)
{
this.interfaceType = interfaceType;
this.implementationType = implementationType;
}
// Invoked at build time. We return the interface we want to implement.
protected override Type[] GetPublicInterfaces(Type targetType)
{
return new[] { this.interfaceType };
}
// Invoked at run time.
public override object CreateImplementationObject(AdviceArgs args)
{
return Activator.CreateInstance(this.implementationType);
}
}
[Serializable]
[ProvideAspectRole("INTERCEPTOR")]
[MulticastAttributeUsage(MulticastTargets.Method)]
[AspectRoleDependency(AspectDependencyAction.Order, AspectDependencyPosition.After, "COMPOSER")]
public sealed class InterceptAspectAttribute : MethodInterceptionAspect
{
public override void CompileTimeInitialize(MethodBase method, AspectInfo aspectInfo)
{
base.CompileTimeInitialize(method, aspectInfo);
// Warning in VS output
Message.Write(method, SeverityType.Warning, "XXX", "Method: " + method.Name);
}
public override void OnInvoke(MethodInterceptionArgs args)
{
Console.WriteLine("Intercepted before");
args.Proceed();
Console.WriteLine("Intercepted after");
}
}
interface ITest
{
void Call();
}
class TestImpl : ITest
{
public void Call()
{
Console.WriteLine("CALL remote implemented");
}
}
[InterceptAspect(AspectPriority = 1)]
[ComposeAspect(typeof(ITest), typeof(TestImpl), AspectPriority = 2)]
class Test
{
// this should, after compilation, have all methods of ITest, implemented through an instance of TestImpl, which get intercepted before TestImpl is called
public void CallLocalImplementedTest()
{
Console.WriteLine("CALL local implemented");
}
}
class Program
{
static void Main()
{
var test = new Test();
ITest t = Post.Cast<Test, ITest>(test);
Console.WriteLine("TEST #1");
t.Call();
Console.WriteLine("TEST #2");
test.CallLocalImplementedTest();
Console.ReadLine();
}
}
}
I have tried to influence the execution order of the two aspects by
AspectRoleDependency, making the interceptor depend on the composer to run first
AspectPriority, also making the composer run first.
As the tests always yield
TEST #1
CALL remote implemented
TEST #2
Intercepted before
CALL local implemented
Intercepted after
it obviously doesn't work. Do you have a clue why my execution order has not changed? Did I do something wrong, did I miss a detail in the documentation? What can I do to intercept my composition-injected methods as well?

With the current aspects and your current setup you cannot achive your desired result.
The problem is in how Postsharp work: it does the IL waving in one step and it only applies the InterceptAspect to the methods which are present at original compile time so it does not see the new interface implementations added with the ComposeAspect.
So no ordering of the accepts or providing roles, priorities or other configuration would help here.
One workaround would be to add the InterceptAspect on the injected TestImpl class:
[InterceptAspect]
class TestImpl : ITest
{
public void Call()
{
Console.WriteLine("CALL remote implemented");
}
}
In this case the logging logic will be added directly TestImpl so these method will contain the logging when it will be composed into your Test class.
Or if you don't mark every implementation you can put your aspect on the interface itself with:
[InterceptAspect(AttributeInheritance = MulticastInheritance.Multicast)]
interface ITest
{
void Call();
}

Related

ForPartsOf received calls not showing up

For testing purposes I want to run the real implementation of a class but see the functions that where called on it after its execution. If I understood that documentation correctly that is what the ForPartsOf is for. However after using it, it never returns any used calls (while I know they get triggered by breakpoints).
I created a small program to reflect my problem, at the end I would expect the console output to tell me both instances received 2 calls. but the 'real' one returns 0.
test interface:
public interface ITestClass
{
string DoSomething();
}
test class:
public class TestClass : ITestClass
{
private readonly string mOutput;
public TestClass(string output)
{
mOutput = output;
}
public string DoSomething()
{
return mOutput;
}
}
test program:
//using NSubstitute;
//using System;
//using System.Linq;
private const int cItterations = 2;
public void Run()
{
ITestClass mock = Substitute.For<ITestClass>();
mock.DoSomething().Returns("fake");
ITestClass real = Substitute.ForPartsOf<TestClass>("real");
RunCalls(mock); //fake, fake
Console.WriteLine();
RunCalls(real); //real, real
Console.WriteLine();
Console.WriteLine($"mock calls: {mock.ReceivedCalls().Count()}"); //mock calls: 2
Console.WriteLine($"real calls: {real.ReceivedCalls().Count()}"); //real calls: 0 (expected 2?)
}
private void RunCalls(ITestClass implementation)
{
for (int i = 0; i < cItterations; i++)
{
Console.WriteLine(implementation.DoSomething());
}
}
I'm most likely doing something wrong but I can't seem to figure out what it is. Any help would be appreciated.
using:
ms .net 4.7.2 with NSubstitute 4.0.0 (via nuget)
NSubstitute cannot intercept non-virtual class members. (For an explanation as to why, please see the non-virtual members section of the How NSubstitute works documentation.)
Try it with DoSomething declared as a virtual member:
public class TestClass : ITestClass
{
// ... other members elided ...
public virtual string DoSomething()
{
return mOutput;
}
}
Adding the NSubstitute.Analyzers package to your test projects will pick up cases where non-virtual members are used with NSubstitute.

How to initialize class before it is needed in the Main method using C#

Given this code:
using System;
using System.Collections.Generic;
using FactoryCallback = System.Func<System.Object>;
interface IMessageProvider
{
string Message { get; }
}
class MessageProvider : IMessageProvider
{
private Random generator = new Random();
public static void Register()
{
InstanceFactory.Register(typeof(IMessageProvider), () => new MessageProvider());
}
public string Message
{
get
{
switch (generator.Next(3))
{
case 0:
return "No matter where you go, there you are.";
case 1:
return "Once I thought I'd made a mistake, but I was wrong.";
case 2:
return "I used to think I was indecisive; now I'm not so sure";
default:
throw new IndexOutOfRangeException();
}
}
}
}
class InstanceFactory
{
private static Dictionary<Type, FactoryCallback> typeCallbacks =
new Dictionary<Type, FactoryCallback>();
public static void Register(Type type, FactoryCallback callback)
{
typeCallbacks.Add(type, callback);
}
public static Object InstanceOf(Type type)
{
return typeCallbacks[type]();
}
}
public class RandomMessage
{
public static void Main()
{
IMessageProvider provider =
InstanceFactory.InstanceOf(typeof(IMessageProvider)) as IMessageProvider;
Console.WriteLine(String.Format("The message is:\n{0}", provider.Message));
}
}
This program will not run successfully as is because the MessageProvider never actually registers with the InstanceFactory.
Obviously, a call to MessageProvider.Register could be added to the beginning of RandomMessage.Main. However, that now requires RandomMessage to have knowledge of MessageProvider and defeats the whole purpose of the InstanceFactory class which is intended to separate how to create something from what that something does.
I would like the MessageProvider to be able to automatically register with the InstanceFactory before RandomMessage.Main tries to create an IMessageProvider instance.
How could this be accomplished?
The registration of service IMessageProvider and component MessageProvider with InstanceFactory is not the responsbility of the MessageProvider implementation, it is an infrastructure concern for the application, therefore should be done inside of the Main method.
public class RandomMessage
{
public static void Main()
{
// Register services with InstanceFactory at the start of Main method
InstanceFactory.Register(typeof(IMessageProvider), () => new MessageProvider());
IMessageProvider provider = InstanceFactory.InstanceOf(typeof(IMessageProvider)) as IMessageProvider;
Console.WriteLine(String.Format("The message is:\n{0}", provider.Message));
}
}
If you somehow referenced MessageProvider before calling InstanceFactory.InstanceOf(), you could just add a static constructor to MessageProvider class:
static MessageProvider()
{
Register();
}
If it's not an option, you can do it via reflection by adding a custom attribute to all classes you want to register and calling Register() for all of them in static constructor of InstanceFactory like described here.
Consider using some Inversion of Control library. like Unity (but it might be overkill) or SimpleContainer.
Then you will 'Register' instance of interfaces while your app start (in examples you should have file like 'bootstrapper.cs' )

limit method to only be called by a particular class

I want a particular method in one class to only be accessible by a particular class. For example:
public class A
{
public void LimitedAccess() {}
public void FullAccess() {}
}
public class B
{
public void Func()
{
A a = new A();
a.LimitedAccess(); // want to be able to call this only from class B
}
}
public class C
{
public void Func()
{
A a = new A();
a.FullAccess(); // want to be able to call this method
a.LimitedAccess(); // but want this to fail compile
}
}
Is there is a keyword or attribute that I can use to enforce this?
UPDATE:
Due to existing system complexity and time constraints, I needed a low impact solution. And I wanted something to indicate at compile time that LimitedAccess() could not be used. I trust Jon Skeet's answer that exactly what I had asked for could not be done in C#.
The question and Jon's answer are good for those who may run across this later. And the fact that this design smells can hopefully veer anyone away for choosing something like this as a desired a solution.
As mentioned in a comment, the C# friend conversation is useful reading if you are trying to solve a similar situation.
As for my particular solution: "why would A contain B's logic" (asked by #sysexpand in comments). That's the rub. B.Func() was called throughout the system I'm working on, but it primarily operated on a singleton of A. So what I ended up doing was moving B's Func() into A and making A.LimitedAccess() private. There were a few other details to work around, as there always are, but I got a low impact solution that gave me compile-time errors on callers to A.LimitedAccess().
Thanks for the discussion.
No. The only thing you could do would be to make LimitedAccess a private method, and nest class B within class A.
(I'm assuming you want all the classes in the same assembly. Otherwise you could put A and B in the same assembly, and C in a different assembly, and make LimitedAccess an internal method.)
Yes. What you are asking for is perfectly possible.
You can restrict access to methods and variables for a specific instance, by using an interface.
However, an interface alone cannot prevent someone from creating their own instance of the class, at which point they will have full access to that instance.
To do that, next you should nest it as a private class inside of another class in order to restrict access to the constructor.
Now you have a particular method in one class to only be accessible by a particular class.
In this example, only class B is ever able to access function LimitedAccess.
public interface IA
{
void FullAccess();
}
public class B
{
private class A : IA
{
public void LimitedAccess() {} //does not implement any interface
public void FullAccess() {} //implements interface
}
private A a = new A();
public IA GetA()
{
return (IA)a;
}
public void Func()
{
/* will be able to call LimitedAccess only from class B,
as long as everybody else only has a reference to the interface (IA). */
a.LimitedAccess();
}
}
//This represents all other classes
public class C
{
public void Func(IA ia)
{
ia.FullAccess(); // will be able to call this method
ia.LimitedAccess(); // this will fail to compile
}
}
public static class MainClass
{
public static void Main(string[] args)
{
B b = new B();
b.Func();
IA ia = b.GetA();
C c = new C();
c.Func(ia);
}
}
In case you just want to remind yourself (or team mates) to not call LimitedAccess everywhere, you could consider using explicit interface implementation or mark LimitedAccess as obsolete.
public interface IA
{
void LimitedAccess();
void FullAccess();
}
public class A : IA
{
private void LimitedAccess() { }
public void FullAccess() { }
void IA.LimitedAccess() => LimitedAccess();
void IA.FullAccess() => FullAccess();
}
public class B
{
public void Func()
{
IA a = new A();
a.LimitedAccess(); // want to be able to call this only from class B
}
}
public class C
{
public void Func()
{
A a = new A();
a.FullAccess(); // want to be able to call this method
a.LimitedAccess(); // -> fails to compile
}
}
Maybe this is a workaround.
Use the System.Runtime.CompilerServices and then you can either check the Name of the calling function and/or the file, in which the calling function is defined. If you have a class per file, the filename might be a substitude for the class name. Check it and block the call.
internal void MySecretFunction (string something,
[CallerMemberName] string memberName = null,
[CallerFilePath] string filePath = null,
[CallerLineNumber] int lineNumber = 0) {
if (!filePath.EndsWith(#"\goodClass.cs")) return;
// else do something
}
You could always see the calling type with a StackTrace.
Just note that when building in release mode, the call on the stack will get optimized, and its possible that the stack trace could return a completely different class, so just make sure to test it before you publish.
/// <summary>
/// Warning: Any class that calls this other than "B" will throw an exception.
/// </summary>
public void LimitedAccess()
{
if (new System.Diagnostics.StackTrace().GetFrame(1).GetMethod().DeclaringType != typeof(B)) throw new Exception("Invalid Caller Type, B is only class able to call this method.");
}
Unfortunately you wont be able to know if its an error on compile time. Best you can do is throw an exception if it gets called, and add a comment warning people about it.
It is against OOP best practices to make such a design. Methods of classes are not supposed to be protected from being called.
If your design requires control over calling a method, then control should be exercised by testing the arguments - caller which is authorized to make a call would "know" the magic word to pass as the argument.
This is a variation of the solution suggested by #cowlinator using class AWithUnlimitedAccess derived from class A rather than class A implementing interface IA.
The result and the limitations are the same, but I like it better because (1) the limited access methods are defined inside its own class and (2) it's easier to add documentation comments.
public class A
{
public void FullAccess() { }
}
public class AWithUnlimitedAccess : A
{
public void LimitedAccess() { }
}
public class B
{
private AWithUnlimitedAccess a = new AWithUnlimitedAccess();
public A GetA()
{
return a;
}
public void Func()
{
a.FullAccess();
a.LimitedAccess();
}
}
// This represents all other classes
public class C
{
public A A;
public void Func()
{
A.FullAccess();
A.LimitedAccess(); // this will fail compile
}
}
public static class MainClass
{
static void Main(string[] args)
{
B b = new B();
b.Func();
C c = new C();
c.A = b.GetA();
c.Func();
}
}

How to know whether a class method was called internally or remotely in .NET Remoting?

I have a class which needs to behave differently when being called remotely via .Net remoting. How can I determine, inside the class, if this is the case?
class RemoteClass : MarshalByRefObject
{
public void SomeMethod ()
{
if (ConditionWhatINeed) //If this method was called internally/remotely
{
//Do one stuff
}
else
{
//Do another suff
}
}
you may want to have a look at the RemotingServices.IsObjectOutOfContext Method. it also has an example you may find useful. of course, because you'll be calling this method server-side on 'this' it will never be seen as a remoting object but if you add a parameter to your method than that parameter will be in local context if not remoting and out of context when remoting (PS this is an unverified assumption on my account). Another useful helper may be the RemotingServices.IsTransparentProxy Method.
There may be a way using one of the *Services objects under the System.Runtime.Remoting hierarchy, as mtijn indicated. However, you have deep problems in your object model. Having dual responsibility on objects is bad practice, difficult to maintain and difficult to understand. Why not rather expose a dedicated 'remote' object; the following sample demonstrates it:
class Program
{
static void Main(string[] args)
{
InitializeRemoting();
var remote = GetRemotingObject("localhost");
var local = new LocalClass();
remote.SomeMethod();
local.SomeMethod();
Console.ReadLine();
}
static void InitializeRemoting()
{
var c = new TcpServerChannel(9000);
ChannelServices.RegisterChannel(c, false);
WellKnownServiceTypeEntry entry = new WellKnownServiceTypeEntry
(
typeof(RemoteClass),
"LocalClass", // Lie about the object name.
WellKnownObjectMode.Singleton
);
RemotingConfiguration.RegisterWellKnownServiceType(entry);
}
static LocalClass GetRemotingObject(string serverName)
{
TcpClientChannel channel = new TcpClientChannel("tcp-client", new BinaryClientFormatterSinkProvider());
ChannelServices.RegisterChannel(channel, false);
return (LocalClass)Activator.GetObject
(
typeof(LocalClass), // Remoting will happily cast it to a type we have access to.
string.Format("tcp://{0}:9000/LocalClass", serverName)
);
}
}
public class LocalClass : MarshalByRefObject
{
public void SomeMethod()
{
OnSomeMethod();
}
protected virtual void OnSomeMethod()
{
// Method called locally.
Console.WriteLine("Local!");
}
}
// Note that we don't need to (and probably shouldn't) expose the remoting type publicly.
class RemoteClass : LocalClass
{
protected override void OnSomeMethod()
{
// Method called remotely.
Console.WriteLine("Remote!");
}
}
// Output:
// Remote!
// Local!
Edit: To answer your question directly, even though what you are trying to achieve is bad practice, duplicate my code and simply provide a virtual bool IsLocal { get { return true; } } on the local class and override it on the remote class. You can then use the property in your if statements.
Edit: If you server and your clients needs to share the exact same instance of the class you should use the Facade Pattern. For example:
class CommonImplementation
{
public static readonly CommonImplementation Instance = new CommonImplementation();
private CommonImplementation() { }
public void SomeMethod(string someArg, bool isServerCall)
{
if (isServerCall)
{
Console.WriteLine("Remote! {0}", someArg);
}
else
{
Console.WriteLine("Local! {0}", someArg);
}
}
}
// These two classes are the facade.
public class LocalClass : MarshalByRefObject
{
public virtual void SomeMethod(string someArg)
{
CommonImplementation.Instance.SomeMethod(someArg, false);
}
}
class RemoteClass : LocalClass
{
public override void SomeMethod(string someArg)
{
CommonImplementation.Instance.SomeMethod(someArg, true);
}
}

Virtual Extension Methods?

I have a class that gets used in a client application and in a server application.
In the server application, I add some functionality to the class trough extension methods. Works great. Now I want a bit more:
My class (B) inherits from another class (A).
I'd like to attach a virtual function to A (let's say Execute() ), and then implement that function in B. But only in the server. The Execute() method would need to do stuff that is only possible to do on the server, using types that only the server knows about.
There are many types that inherit from A just like B does, and I'd like to implement Execute() for each of them.
I was hoping I could add a virtual extension method to A, but that idea doesn't seem to fly. I'm looking for the most elegant way to solve this problem, with or without extension methods.
No, there aren't such things as virtual extension methods. You could use overloading, but that doesn't support polymorphism. It sounds like you might want to look at something like dependency injection (etc) to have different code (dependencies) added in different environments - and use it in regular virtual methods:
class B {
public B(ISomeUtility util) {
// store util
}
public override void Execute() {
if(util != null) util.Foo();
}
}
Then use a DI framework to provide a server-specific ISomeUtility implementation to B at runtime. You can do the same thing with a central static registry (IOC, but no DI):
override void Execute() {
ISomeUtility util = Registry.Get<ISomeUtility>();
if(util != null) util.Foo();
}
(where you'd need to write Registry etc; plus on the server, register the ISomeUtility implementation)
You can use the new dynamic type functionality to avoid having to build a registry of types to methods:
using System;
using System.Collections.Generic;
using System.Linq;
using visitor.Extension;
namespace visitor
{
namespace Extension
{
static class Extension
{
public static void RunVisitor(this IThing thing, IThingOperation thingOperation)
{
thingOperation.Visit((dynamic)thing);
}
public static ITransformedThing GetTransformedThing(this IThing thing, int arg)
{
var x = new GetTransformedThing {Arg = arg};
thing.RunVisitor(x);
return x.Result;
}
}
}
interface IThingOperation
{
void Visit(IThing iThing);
void Visit(AThing aThing);
void Visit(BThing bThing);
void Visit(CThing cThing);
void Visit(DThing dThing);
}
interface ITransformedThing { }
class ATransformedThing : ITransformedThing { public ATransformedThing(AThing aThing, int arg) { } }
class BTransformedThing : ITransformedThing { public BTransformedThing(BThing bThing, int arg) { } }
class CTransformedThing : ITransformedThing { public CTransformedThing(CThing cThing, int arg) { } }
class DTransformedThing : ITransformedThing { public DTransformedThing(DThing dThing, int arg) { } }
class GetTransformedThing : IThingOperation
{
public int Arg { get; set; }
public ITransformedThing Result { get; private set; }
public void Visit(IThing iThing) { Result = null; }
public void Visit(AThing aThing) { Result = new ATransformedThing(aThing, Arg); }
public void Visit(BThing bThing) { Result = new BTransformedThing(bThing, Arg); }
public void Visit(CThing cThing) { Result = new CTransformedThing(cThing, Arg); }
public void Visit(DThing dThing) { Result = new DTransformedThing(dThing, Arg); }
}
interface IThing {}
class Thing : IThing {}
class AThing : Thing {}
class BThing : Thing {}
class CThing : Thing {}
class DThing : Thing {}
class EThing : Thing { }
class Program
{
static void Main(string[] args)
{
var things = new List<IThing> { new AThing(), new BThing(), new CThing(), new DThing(), new EThing() };
var transformedThings = things.Select(thing => thing.GetTransformedThing(4)).Where(transformedThing => transformedThing != null).ToList();
foreach (var transformedThing in transformedThings)
{
Console.WriteLine(transformedThing.GetType().ToString());
}
}
}
}
I would suggest something like the following. This code could be improved by adding support for detecting intermediate class hierarchy types that don't have a dispatch mapping and calling the nearest dispatch method based on the runtime hierarchy. It could also be improved by using reflection to detect overload of ExecuteInteral() and adding them automatically to the dispatch map.
using System;
using System.Collections.Generic;
namespace LanguageTests2
{
public class A { }
public class B : A {}
public class C : B {}
public static class VirtualExtensionMethods
{
private static readonly IDictionary<Type,Action<A>> _dispatchMap
= new Dictionary<Type, Action<A>>();
static VirtualExtensionMethods()
{
_dispatchMap[typeof(A)] = x => ExecuteInternal( (A)x );
_dispatchMap[typeof(B)] = x => ExecuteInternal( (B)x );
_dispatchMap[typeof(C)] = x => ExecuteInternal( (C)x );
}
public static void Execute( this A instance )
{
_dispatchMap[instance.GetType()]( instance );
}
private static void ExecuteInternal( A instance )
{
Console.WriteLine("\nCalled ToString() on: " + instance);
}
private static void ExecuteInternal(B instance)
{
Console.WriteLine( "\nCalled ToString() on: " + instance );
}
private static void ExecuteInternal(C instance)
{
Console.WriteLine("\nCalled ToString() on: " + instance);
}
}
public class VirtualExtensionsTest
{
public static void Main()
{
var instanceA = new A();
var instanceB = new B();
var instanceC = new C();
instanceA.Execute();
instanceB.Execute();
instanceC.Execute();
}
}
}
Virtual implies inheritance in a OOP way and extension methods are "just" static methods that through a bit a syntactic sugar the compiler allows you to pretend to call on an instance of the type of its first parameter. So no, virtual extension methods are out of the question.
Check out the answer by Marc Gravell for a possible solution to your problem.
You can implement a service register. Example (server side):
static IDictionary<Type, IService> serviceRegister;
public void ServerMethod(IBusinessType object)
{
serviceRegister[obect.GetType()].Execute(object);
}
What you need are rather services in your server, which implement server side functionality, instead of extension methods. I wouldn't put to much logic into extension methods.
Let me check: you have a class hierarchy inheriting from A, presumably structured according to your business domain. Then you want to add behaviours depending on where the classes execute. So far you've used extension methods, but now you find you cannot get them to vary with your class hierarchy. What kinds of behaviours are you attaching at the server?
If it's stuff like transaction management and security, policies implemented through dependency injection à la Marc's suggestion should work well. You could also consider implementing the Strategy pattern through delegates and lambdas, for a more limited version of DI. However, what's not clear is how client code currently uses your classes and their extension methods on the server. How dependent are other classes on how you add the server-side functionality? Are they server-side only classes that currently expect to find the extension methods?
In any case, it sounds like you're going to need a careful testability design and testing strategy since you are introducing variation along two simultaneous dimensions (inheritance hierarchy, execution environment). You are using unit testing, I trust? Check that whatever solution you choose (e.g. DI through configuration) interacts well with testing and mocking.

Categories

Resources