How to create a lazy singleton aspect with PostSharp? - c#

Assuming the following singleton declaration for a sealed class with a private constructor:
private static readonly Lazy<MyClass> _singleton = new Lazy<MyClass>(() => new MyClass());
public static MyClass Instance => _singleton.Value;
Is there a way to create a PostSharp aspect that would allow me to add an attribute (PsSingleton) to the Instance property as such:
[PsSingleton]
public static MyClass Instance {get; set;}
and have the class become a lazy singleton at run-time?

using PostSharp.Aspects;
using PostSharp.Reflection;
using PostSharp.Serialization;
using System;
using System.Reflection;
namespace LazySingletonSample
{
class Program
{
static void Main(string[] args)
{
TestClass.Instance.SayHello();
TestClass.Instance.SayHello();
TestClass.Instance.SayHello();
}
}
public class TestClass
{
[LazySingleton]
public static TestClass Instance;
public void SayHello()
{
Console.WriteLine("Hello from singleton!");
}
}
// TODO: Restrict usage
[PSerializable]
public sealed class LazySingletonAttribute : LocationInterceptionAspect
{
object singletonInstance;
ConstructorInfo constructor;
public override bool CompileTimeValidate(LocationInfo locationInfo)
{
// TODO: check that:
// - field name is "Instance"
// - field type is the same as the declaring type
// - there is only a default constructor
// - the constructor is private
// - the constructor is not called anywhere
// - the field is not set anywhere
return true;
}
public override void CompileTimeInitialize(LocationInfo targetLocation, AspectInfo aspectInfo)
{
this.constructor = targetLocation.DeclaringType.GetConstructor(new Type[] { });
}
public override void OnGetValue(LocationInterceptionArgs args)
{
if (this.singletonInstance == null)
{
Console.WriteLine("Creating singleton instance.");
this.singletonInstance = constructor.Invoke(new object[] { });
}
Console.WriteLine("Returning singleton instance.");
args.Value = this.singletonInstance;
}
public override void OnSetValue(LocationInterceptionArgs args)
{
throw new InvalidOperationException();
}
}
}

Related

How to call static method of static generic class with C# Reflection?

I have many classes with these implementations:
internal static class WindowsServiceConfiguration<T, Y> where T : WindowsServiceJobContainer<Y>, new() where Y : IJob, new()
{
internal static void Create()
{
}
}
public class WindowsServiceJobContainer<T> : IWindowsService where T : IJob, new()
{
private T Job { get; } = new T();
private IJobExecutionContext ExecutionContext { get; }
public void Start()
{
}
public void Install()
{
}
public void Pause()
{
}
public void Resume()
{
}
public void Stop()
{
}
public void UnInstall()
{
}
}
public interface IWindowsService
{
void Start();
void Stop();
void Install();
void UnInstall();
void Pause();
void Resume();
}
public class SyncMarketCommisionsJob : IJob
{
public void Execute(IJobExecutionContext context)
{
}
}
public interface IJob
{
void Execute(IJobExecutionContext context);
}
I would like to call Create() method of WindowsServiceConfiguration static class by reflection as below:
WindowsServiceConfiguration<WindowsServiceJobContainer<SyncMarketCommisionsJob>, SyncMarketCommisionsJob>.Create();
and I don't know how to do that by using Activator or something like that in order to call Create method in my C# code?
best regards.
Something like this ought to work:
// Get the type info for the open type
Type openGeneric = typeof(WindowsServiceConfiguration<,>);
// Make a type for a specific value of T
Type closedGeneric = openGeneric.MakeGenericType(typeof(WindowsServiceJobContainer<SyncMarketCommisionsJob>), typeof(SyncMarketCommisionsJob));
// Find the desired method
MethodInfo method = closedGeneric.GetMethod("Create", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod);
// Invoke the static method
method.Invoke(null, new object[0]);

How to allow a different singleton class to be instantiated by passing different parameters into the constructor

I have a class in my project and I want to instantiate it only once by passing a specific parameter via the constructor, but when I pass different parameter it should instantiate a new one. How I can achieve this with the singleton design pattern? Or can you suggest another design pattern if it can't be achieved with a singleton?
class Program
{
static void Main()
{
SiteStructure s = SiteStructure.Instance;
}
}
public sealed class SiteStructure
{
static readonly SiteStructure _instance = new SiteStructure();
public static SiteStructure Instance
{
get
{
return _instance;
}
}
SiteStructure()
{
// Initialize.
}
}
You have to modify the way the _instance variable is initialised, making use of a function that accepts the parameter value that you want to pass in. Also, the _instance variable can no longer be readonly as it needs to be initialised inside of the new function.
[TestMethod]
public void CreateSingletonInstance()
{
SiteStructure s = SiteStructure.GetInstance("Abc123");
Debug.Print(s.Parameter); // outputs Abc123
SiteStructure s2 = SiteStructure.GetInstance("Is it really a singleton?");
Debug.Print(s2.Parameter); // outputs Is it really a singleton?
SiteStructure s3 = SiteStructure.GetInstance("Abc123");
Debug.Print(s3.Parameter); // outputs Abc123
Assert.AreNotEqual(s, s2); // Check to make sure they are different instances
Assert.AreEqual(s, s3); // Check to make sure they are the same instance
}
public sealed class SiteStructure
{
static Dictionary<string, SiteStructure> _siteStructures = new Dictionary<string, SiteStructure>();
static object _instance_Lock = new object();
public static SiteStructure GetInstance(string parameter)
{
if (!_siteStructures.ContainsKey(parameter))
{
lock (_instance_Lock)
{
if (!_siteStructures.ContainsKey(parameter))
{
_siteStructures.Add(parameter, new SiteStructure(parameter));
}
}
}
return _siteStructures[parameter];
}
private SiteStructure(string parameter)
{
// Initialize.
Parameter = parameter;
}
public string Parameter { get; set; }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace Rextester
{
public class Program
{
public static void Main(string[] args)
{
var g = SiteStructure.Instance(4);
}
}
public sealed class SiteStructure {
public static SiteStructure Instance()
{ return new SiteStructure();
}
public static SiteStructure Instance (int x)
{ return new SiteStructure (x);
}
SiteStructure() { }
SiteStructure(int x) { Console.WriteLine("Hello"); }
}
}

MS unity container

I have an interface IInterface and it looks something like below -
public interface IInterface
{
void SomeMethod1();
void SomeMethod2();
void SomeMethod3();
.
.
.
}
One of the implementations is something like -
public class Implementation : IInterface
{
private Object obj;
public Implementation(Object obj)
{
this.obj = obj;
// Do Something
}
public void SomeMethod1()
{
lock(obj)
{
// Do Something
}
}
public void SomeMethod2()
{
// Do Something
}
public void SomeMethod3()
{
lock(obj)
{
// Do Something
}
}
.
.
.
}
How to pass a static readonly instance of type Object while registering Implementation class with type IInterface via unity configuration?
My preferred approach is probably to create a factory for creating IInterfaces
public interface IInterface
{
void SomeMethod1();
}
public interface IInterfaceFactory
{
IInterface CreateInterface();
}
public class StandardInterfaceFactory : IInterfaceFactory
{
// Define your static lock object here. Other customers
// can define their own IInterfaceFactory to use a
// different lock object.
private static readonly object lockObject = new object();
public IInterface CreateInterface()
{
return new StandardInterface(lockObject);
}
}
public class StandardInterface : IInterface
{
private readonly object lockObject;
public StandardInterface(object lockObject)
{
this.lockObject = lockObject;
}
public void SomeMethod1()
{
lock (this.lockObject)
{
Console.WriteLine("I've locked on " + lockObject);
}
}
}
Your unity configuration and client code will then look like this.
void Main()
{
IUnityContainer container = new UnityContainer();
// This mapping can be done trivially in XML configuration.
// Left as an exercise for the reader :)
container.RegisterType<IInterfaceFactory, StandardInterfaceFactory>();
IInterfaceFactory factory = container.Resolve<IInterfaceFactory>();
IInterface myInterface = factory.CreateInterface();
myInterface.SomeMethod1();
}

Derived types with Method overloading

The code is simple enough to understand I hope.
I'm trying to use an interface type IColor in order to pass color objects to the ColorManager. I then want the ColorManager to pass this object to the IColor object as its own type, so the method overloads gets called.
However, it seems since it is being passed as the IColor type, C# will not implicity cast it into its complete type as either a BlueColor or GreenColor.
I hope this makes some sense to somebody on what I want to achieve. Is this possible in C#?
[Solution]
http://msdn.microsoft.com/en-us/library/dd264736.aspx
Overload Resolution with Arguments of Type dynamic
My code so far:
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.IO;
namespace Example
{
public interface IColor
{
void CatchColor(IColor c);
}
public class BlueColor : IColor
{
public void CatchColor(IColor c)
{
}
}
public class GreenColor : IColor
{
public void CatchColor(BlueColor c)
{
Console.WriteLine("CAUGHT BLUE!");
}
public void CatchColor(GreenColor c)
{
Console.WriteLine("CAUGHT GREEN!");
}
public void CatchColor(IColor c)
{
Console.WriteLine("CAUGHT SOME COLOR!");
}
}
public class ColorManager
{
public void PassColor(IColor c)
{
// Don't use static type-checking
// Problem solved
dynamic AnyColor = c;
AnyColor.CatchColor(AnyColor);
}
public static void Main()
{
GreenColor G = new GreenColor();
new ColorManager().PassColor(G);
Console.ReadLine();
return;
}
}
}
One possiblity to tell the ColorManager class to use the correct type of the passed object is to use an abstract class, that already implements the CatchColor:
public abstract class IColor
{
// override in every class
public abstract void PrintColor();
// has the correct type passed with the interface
public void CatchColor(IColor c)
{
c.PrintColor();
}
}
Then the sub classes need to implement only PrintColor with the correct color:
public class BlueColor : IColor
{
public override void PrintColor()
{
Console.WriteLine("BLUE!");
}
}
public class GreenColor : IColor
{
public override void PrintColor()
{
Console.WriteLine("GREEN!");
}
}
The manager is the same:
public class ColorManager
{
public void PassColor(IColor c)
{
c.CatchColor(c);
}
}
It can be used like this:
GreenColor G = new GreenColor();
var cm = new ColorManager();
cm.PassColor(G);
cm.PassColor(new BlueColor());
The outputs is:
GREEN!
BLUE!
What you want is late method binding.
The downside to this is you have to add methods for each new type of color. The upside is you don't have to maintain a case statement or conditional logic.
See here for more detail:
Early and late binding
Edit: Here is a working example of this type of late-binding.
class Program {
static void Main(string[] args) {
//Declare instances
BaseClass myClass = new Class2();
BaseClass otherClass = new Class1();
//Invoke the action method which will match based on the BaseClass type
Action(myClass);
Action(otherClass);
Console.ReadLine();
}
public static void Action(BaseClass classType) {
//Remove the compile-time type so the runtime can select the method based on signature
dynamic aClass = classType;
ServiceMethod(aClass);
}
public static void ServiceMethod(dynamic input) {
Methods(input);
}
public static void Methods(Class1 classType) {
Console.WriteLine("Class1");
Debug.WriteLine("Class1");
}
public static void Methods(Class2 classtype) {
Console.WriteLine("Class2");
Debug.WriteLine("Class2");
}
public static void Methods(Class3 classType) {
Console.WriteLine("Class3");
Debug.WriteLine("Class3");
}
}
public abstract class BaseClass { //This could also be an interface
public Guid Id { get; set; }
public string Name { get; set; }
}
public class Class1 : BaseClass {
}
public class Class2 : BaseClass{
}
public class Class3 : BaseClass {
}
So you want something like:
public void CatchColor(Color c)
{
if (c is BlueColor)
CatchColor(c as BlueColor);
if (c is GreenColor)
CatchColor(c as GreenColor);
}
?

Get the name of the class where the object was created

I have two classes as follow:
First one:
class Class1
{
private void Method1()
{
var obj=new TestClass();
obj.TestMethod1();
}
}
Second One:
class TestClass
{
public void TestMethod1()
{
TestMethod2();
}
private void TestMethod2()
{
//get the calling class
}
}
When Class1.Method1 calls TestClass.TestMethod1 which in turn calls TestClass.TestMethod2, I want to get the fully qualified class name of Class1 inside TestClass.TestMethod2. I have seen this link, but I think I will get TestClass.TestMethod1 as method name and TestClass as the class name. How can I get the calling class name?
There is no nice way to do that. You can access the stack-frames (just look at the second frame, rather than the first) - but that is expensive and brittle. You could use optional caller-member-name attributes (being explicit from TestMethod1) to get hold of "Method1", but not the "Class1" part. One other option would be to pass in an object (or just the name) explicitly; for example:
private void Method1()
{
var obj=new TestClass();
obj.TestMethod1(this);
}
public void TestMethod1(object caller=null,
[CallerMemberName] string callerName=null)
{
TestMethod2(caller??this,callerName??"TestMethod1");
}
private void TestMethod2(object caller=null,
[CallerMemberName] string callerName=null)
{
string callerName = ((caller??this).GetType().Name) + "." + callerName
//get the calling class
}
but I have to confess that is pretty ugly
Perhaps better would be to question why you need this in the first place.
Could you not pass the type into the second class via constructor like:
class Class1
{
private void Method1()
{
Type t = typeof(Class1);
var obj = new TestClass(t);
obj.TestMethod1();
}
}
class TestClass
{
private Type _caller;
public TestClass(Type type)
{
_caller = type;
}
public void TestMethod1()
{
TestMethod2();
}
private void TestMethod2()
{
//Do something with the class
}
}
You might check out this code to find your solution without having to pass class instances or type parameters, etc....:
class Program
{
static void Main(string[] args)
{
var c = new Class1();
c.Method1();
}
}
class Class1
{
public void Method1()
{
var obj = new TestClass();
obj.TestMethod1();
}
}
class TestClass
{
public void TestMethod1()
{
TestMethod2();
var mth = new StackTrace().GetFrame(1).GetMethod();
var clss = mth.ReflectedType.Name;
Console.WriteLine("Classname in Method1(): {0}", clss);
}
private void TestMethod2()
{
//get the calling class
var mth = new StackTrace().GetFrame(1).GetMethod();
var clss = mth.ReflectedType.Name;
Console.WriteLine("Class in .Method2(): {0}", clss);
}
}
This will get the Type that first called TestClass. It prints:
TestStack.Class1
TestStack.Program
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
namespace TestStack
{
class Class1
{
public void Method1()
{
var obj = new TestClass();
obj.TestMethod1();
}
}
class TestClass
{
public void TestMethod1()
{
TestMethod2();
}
private void TestMethod2()
{
StackTrace st = new StackTrace();
Type calling = null;
foreach (var sf in st.GetFrames())
{
var type = sf.GetMethod().DeclaringType;
if (type != this.GetType())
{
calling = type;
break;
}
}
Console.WriteLine(calling);
}
}
class Program
{
static void Main(string[] args)
{
Class1 class1 = new Class1();
class1.Method1();
TestClass testClass = new TestClass();
testClass.TestMethod1();
}
}
}

Categories

Resources