How to implement a cache attribute? - c#

How can I implement a CacheAttribute so I can have the same logic for all properties in one place?
I am doing this to cache
[TestClass]
public class All
{
public string N
{
get
{
var value =
MemoryCache.Default.Get("Website.Tests.All.N") as string;
if (value != null)
{
return value;
}
value = DateTime.Now.ToString("HH:mm:ss.ffff");
MemoryCache.Default.Add("Website.Tests.All.N", value,
new CacheItemPolicy
{
AbsoluteExpiration =
new DateTimeOffset(DateTime.Now.AddSeconds(5))
});
return value;
}
}
[TestMethod]
public void Extension()
{
var start = N;
Thread.Sleep(1000);
var end = N;
Assert.AreEqual(start, end);
}
}
And I want to use this instead
[TestClass]
public class All
{
[Cache(Duration=5000)]
public string N
{
get
{
return DateTime.Now.ToString("HH:mm:ss.ffff");
}
}
[TestMethod]
public void Extension()
{
var start = N;
Thread.Sleep(1000);
var end = N;
Assert.AreEqual(start, end);
}
}
Is there a way to make this syntax sugar?

It seems you want to "take over" the get method for the property so as to inspect a cache first before returning the "actual" value from your property. Since there is no way to perform property interception on an ad-hoc basis, you'll have to plan ahead for this facility.
One approach would be to use interfaces and write your classes to the interface. For example,
public interface IAll
{
string N { get; set; }
}
Now you can use proxies to create a wrapper around the original instance of All that also implements this interface. Furthermore, since you're fully in charge of the property now, you can check the cache whenever the getter is called. Since you'll have the PropertyInfo/MethodInfo at your disposal, you should have no trouble generating a unique key per property.
So, whenever you would instantiate an instance of All, you also instantiate this proxy, passing it the instance of All. All subsequent usages of that instance of All should instead be passed the proxy. Like any class factory implementation, this requires you to forgo use of the new operator.
Alternatively, you can use virtual methods instead of interfaces.

Related

C# Make a class return its instance without a function or variable

So I've been working with classes with single instances in Unity for a while and generally do this:
class PublicThings {
public static PublicThings I; // instance of this class
public int Score;
void Start { I = GetComponent<PublicThings>(); }
}
Usage: PublicThings.I.Score = 10;
Which works pretty well. However, I've been curious as to whether or not it's possible to have the instance of the class be returned without having to type .I after the class.
So basically here's how it would look instead:
PublicThings.Score = 10;
This question seems like it's relevent but I'm having trouble getting it to work.
Is this possible? If so, how would it be done?
Three options to do what you are looking to do:
Make a static property/field with the static keyword in the PublicThings class
Make a ScriptableObject and attach it to the item that is calling it (video tutorial)
Utilize the Singleton Pattern (I would suggest avoid using this method before trying the other two)
Also it's worth noting that the Singleton Pattern doesn't necessarily solve your problem. You will still have to call something like PublicThings.instance.Score.
Hope this helps.
Singleton pattern is the way to go.
Also, with lazy instantiation.
public class PublicThings
{
private static PublicThings _instance;
// Your private constructor
private PublicThings() { }
public static PublicThings Instance
{
get
{
if (_instance == null)
{
// Construction of instance logic here
_instance = new PublicThings();
}
return _instance;
}
// No setter, read-only property
}
// Decide if Score is a read-only property or not.
public int Score { get; set; }
}
Whener the single instance of PublicThings is required, it will be constructed and then stored. A second access to the instance will provide the stored one.
[Test]
public void WithTwoAccess_ToSingleInstance_MustBeTheSame()
{
var things1 = PublicThings.Instance;
var things2 = PublicThings.Instance;
Assert.AreSame(things2, things1);
// Asserts true
}
If your Score property must be set once, just change que Instance property to a method (commonly called GetInstance) which expects the value of Score.
Hope it helps.

Adding Properties into a List or Collection

I have come across a situation where I probably needed to add properties(of a class) in a list to invoke them manually(or you can say, I need to assign there values(setter)). That is why because, I don't even know which properties is to set the values, but they are decided at runtime. So far I am trying to find out the solution here and there but still I don't get any article that even hints me a work around for this purpose.
Here's what I want to do exactly (mentioned as comments)-
public class DemoClass
{
IList<Properties> _listOfProps;
private int _iFirstProperty;
private string _iSecondProperty;
public DemoClass()
{
_listOfProps = new List<Properties>();
}
public int FirstProperty
{
get
{
return _iFirstProperty;
}
set
{
_iFirstProperty = value;
// Here I want to add this property into the list.
_listOfProps.Add(FirstProperty);
RaisePropertyChanged("FirstProperty");
}
}
public string SecondProperty
{
get
{
return _iSecondProperty;
}
set
{
_iSecondProperty = value;
RaisePropertyChanged("SecondProperty");
}
}
public void HandleChangedProperties()
{
foreach (var list in _listOfProps)
{
// Here I want to invoke the property. ie. sets the 'value' of this property.
list.Invoke(value)
}
}
}
I know, I can use Func to add in the list like- but I can't go with this.
List<Func<int>> listOfFunc = new List<Func<int>>();
listOfFunc.Add(() => { return 0; }); // Adds using lambda expression
listOfFunc.Add(temp); // Adds as a delegate invoker
private int temp()
{
return 0;
}
from MSDN
Properties can be used as if they are public data members, but they
are actually special methods called accessors.
if properties are internally methods, Why they can't be added as List of Func<>
Also, if there's no way I can do that without using Reflection (by getting PropertyInfo list), why Microsoft hasn't designed this in C#?
You can either keep a list of PropertyInfo values and later set the value of the properties using reflection, or you can keep a list of setter delegates (which effectively just forward the value to the real, hidden setter).
For example:
IList<Action<object>> listOfSetters;
listOfSetters.Add(o => this.FirstProperty = (int)o);
// and then:
listOfSetters[0](42); // FirstProperty = 42

How to create a "pointer-like" class, easily exposing functions of member?

What I am trying to do is find the most elegant way to create a "pointer-like" class for a specific object/class type that I have in a project.
What I mean is a little confusing without an example. Take this really simple class:
public class MyClass
{
private string _name;
public string GetName() { return _name; }
public void SetName(string name) { _name = name; }
}
I want to create a second class which is like a pointer to it like this:
public class MyClassPtr
{
private MyClass _obj;
public bool IsValid = false;
public MyClassPtr(MyClass obj) { _obj = obj; IsValid = true; }
public void InvalidatePtr()
{
IsValid = false;
obj = null;
}
// SOME MAGIC HERE?
}
The challenge: The key is that I want to elegantly have MyClassPtr provide an interface to all of the public methods/members in MyClass without writing wrappers and/or accessors around each method/member.
I know that I could do this:
public class MyClassPtr
{
public string GetName() { return _obj.GetName(); }
...
}
But that's what I want to avoid. Is there some fundamental abstraction that I don't know of that I can apply to MyClassPtr to allow it to easily re-expose the methods/members in MyClass directed through _obj? I do NOT want MyClassPtr to inherit MyClass. Should MyClassPtr be a type instead, and some trick with accessors to expose the methods/members of MyClass?
Edit: More context on why I am looking for such a design through an example. Here is the overall goal. Imagine a platform that parses through data about people and when it finds information about a person, it creates an instance of Person with that information. You could get a handle to that person like:
Person person1 = platform.GetPerson(based_on_data);
Now, imagine the platform had two instances of Person that it thought were different people, but all of a sudden information came in that strongly suggested those two instances actually refer to the same person. So, the platform wants to merge the instances together in to a new object, let's call it personX.
Now, floating around in the platform someone had a copy of one of those two instances that got merged, which was person1. What I want to do is on-the-fly replace person1 with personX. Literally, I want person1==personX to be true, NOT just that they are two different objects with the same data. This is important since the platform could make a change to personX and unless the two objects are literally equal, a change to personX would not be automatically reflected in person1.
Since I can't on-the-fly replace person1 with personX I had that idea that I wouldn't give direct access to Person, instead I would give access to PersonPtr which the platform (on-the-fly) can change what Person it is pointing to. This would insurance that once person1ptr gets updated to point to personX, if a change is made in personX it will be seen in person1ptr
You could of course use something like
public class MyClassWrapper
{
MyClass _obj;
public MyClassWrapper(MyClass obj)
{
_obj = obj;
}
public void Invoke(Action<MyClass> action)
{
action(_obj);
}
public U Invoke<U>(Func<MyClass, U> func)
{
return func(_obj);
}
public void ChangeTo(MyClass obj)
{
_obj = obj;
}
}
Given your class looks like
public class MyClass
{
public string Name { get; set; }
}
Example:
var person1 = new MyClass { Name = "Instance1" };
var person2 = new MyClass { Name = "Instance2" };
var wrapper = new MyClassWrapper(person1);
wrapper.Invoke(x => x.Name += "original");
var x = wrapper.Invoke(x => x.Name); // Instance1original
wrapper.ChangeTo(person2);
var y = wrapper.Invoke(x => x.Name); // Instance2
but it has a major drawback: you can't access members directly, so you can't bind the data (to a DataTable or a Control).
It would be better to implement all members of your class also in your wrapper class. If you're afraid changes in your class will be forgotten to be implemented in your wrapper, just use an interface:
public interface IMyClass
{
string Name { get; set; }
}
public class MyClass : IMyClass
{
public string Name { get; set; }
}
public class MyClassWrapper: IMyClass
{
MyClass _obj;
public MyClassWrapper(MyClass obj)
{
_obj = obj;
}
public string Name
{
get { return _obj.Name; }
set { _obj.Name = value; }
}
}
Note that regardless which approach you use, you'll have to always keep a reference to the wrapper instance to actually change the underlying instance (using something like static aside).
Also, changing the underlying instance of such a wrapper without telling the component using it that it changed don't seem to be a good idea. Maybe your system is simple enough to get away with a wrapper; that's something you have to decide for yourself.
Maybe your wrapper should simply have an Invalid flag (and/or use an event to signal a change of the underlying object.). Once the underlying object is merged, it is set to true and each member access should throw an exception. This would force the component using the wrapper to deliberately react to changes and to reload the data from your service.
All in all, I think using such a wrapper will just clutter up your code and be error prone (just imagine adding multithreading to the mix). Think twice if you really need this wrapper.
Why not just simply ask your service for a new instance of your class everytime you use it (the service can simply use a cache)? Sure, you can't prevent that someone somewhere keeps a reference; but at least you'll keep your sanity.

Following the DRY principle in ASP.NET

I have just recently got involved in a classic ASP.NET project which contains lots of storing and reading values from the session and query strings. This could look something like the following:
Session["someKey"]=someValue;
And somewhere else in the code the value in the session is read. Clearly this violates the DRY principle since you'll have the literal string key spread out all over the code. One way to avoid this could be to store all keys as constants that could be referenced everywhere there is a need to read and write to the session. But I'm not sure that's the best way to do it. How would you recommend I best handle this so that I don't violate the DRY principle?
Create a separate public class where you can define your constants, e.g
public class SessionVars
{
public const string SOME_KEY = "someKey";
public const string SOME_OTHER_KEY = "someOtherKey";
}
and then anywhere in your code you can access session variables like this:
Session[SessionVars.SOME_KEY]=someValue;
This way you can get IntelliSence and other bells and whistles.
I think you're reading too much into DRY. I pertains more to things that could be wrapped up in a function. I.e. instead of repeating the same fives lines all over the place wrap those 5 lines in a function and call the function everywhere you need it.
What you have as an example is just setting a value in a dictionary (the session object in this case), and that is the simplest way to store and retrieve objects in it.
I can't remember for the life of me where I humbly re-purposed this code from, but it's pretty nice:
using System;
using System.Web;
namespace Project.Web.UI.Domain
{
public abstract class SessionBase<T> where T : class, new()
{
private static readonly Object _padlock = new Object();
private static string Key
{
get { return typeof(SessionBase<T>).FullName; }
}
public static T Current
{
get
{
var instance = HttpContext.Current.Session[Key] as T;
lock (SessionBase<T>._padlock)
{
if (instance == null)
{
HttpContext.Current.Session[Key]
= instance
= new T();
}
}
return instance;
}
}
public static void Clear()
{
var instance = HttpContext.Current.Session[Key] as T;
if (instance != null)
{
lock (SessionBase<T>._padlock)
{
HttpContext.Current.Session[Key] = null;
}
}
}
}
}
The idea behind it two fold. The type created should be the only type you need. It's basically a big strongly-typed wrapper. So you have some object you want to keep extending information in:
public class MyClass
{
public MyClass()
public string Blah1 { get; set; }
}
Then down the road you extend MyClass and you don't want to have to remember all the Key Values, store them in AppSettings or Const variables in Static Classes. You simply define what you want to store:
public class MyClassSession : SessionBase<MyClass>
{
}
And anywhere in your program you simply use the class.
// Any Asp.Net method (webforms or mvc)
public void SetValueMethod()
{
MyClassSesssion.Current.Blah1 = "asdf";
}
public string GetValueMethod()
{
return MyClassSession.Current.Blah1;
}
Optionally you could place the access to this session object in a base page and wrap it in a property:
class BasePage : Page
{
...
public string MySessionObject
{
get
{
if(Session["myKey"] == null)
return string.Empty;
return Session["myKey"].ToString();
}
set
{
Session["myKey"] = value;
}
}
...
}
Here you are repeating the myKey string but it is encapsulated into the property. If you want to go to the extreme of avoiding this, create a constant with the key and replace the string.

How can I override get and set methods for all properties in a class?

I have got several classes looking like the one below, and I need to do some checks in the get method and custom set methods. Adding the code in each get and set method makes everything look really messed up.
Is there a way I can override the get and set methods for all properties in an entire class?
public class Test
{
private DataRow _dr;
public Test()
{
_dr = GetData();
}
public string Name
{
get { return _dr[MethodBase.GetCurrentMethod().Name.Substring(4)].ToString(); }
set
{
VerifyAccess(MethodBase.GetCurrentMethod().Name.Substring(4), this.GetType().Name);
_dr[MethodBase.GetCurrentMethod().Name.Substring(4)] = value;
}
}
public string Description
{
get { return _dr[MethodBase.GetCurrentMethod().Name.Substring(4)].ToString(); }
set
{
VerifyAccess(MethodBase.GetCurrentMethod().Name.Substring(4), this.GetType().Name);
_dr[MethodBase.GetCurrentMethod().Name.Substring(4)] = value;
}
}
public string DescriptionUrl
{
get { return _dr[MethodBase.GetCurrentMethod().Name.Substring(4)].ToString(); }
set
{
VerifyAccess(MethodBase.GetCurrentMethod().Name.Substring(4), this.GetType().Name);
_dr[MethodBase.GetCurrentMethod().Name.Substring(4)]= value;
}
}
private void VerifyAccess(string propertyname, string classname)
{
//some code to verify that the current user has access to update the property
//Throw exception
}
private DataRow GetData()
{
//Some code to pull the data from the database
}
}
I think what you need is a Proxy on your class, read about Proxy Pattern and Dynamic Proxies
Not directly, there isn't a way to do it with just a compiler. You'd have to generate your entire binary file, then post-process it with some external tool.
This post describes a somewhat similar issue; I hope it helps.
There's a variety of ways to do it.
One would be to create a proxy class (mentioned before), but that would require a lot of refactoring on your behalf.
Another way is with aspects. These do exactly what you're after (insert code based on a pre-requisite.. i.e. all get methods in a class that inherit from x). I ran into a similar problem (actually the exact same problem - checking for security on method calls), and couldn't find cheap/free aspect software that fulfilled my needs.
So, I decided to use Mono-Cecil to inject code before function calls.
If you're interested (it gets a bit messy dealing with IL codes) I can post an old copy of the source
You should extract common code to separate get/set methods, after that you'll be able to add common logic to your properties. By the way, I would do such extraction anyway to avoid copy/paste in the code.
Smth like this:
public string Name
{
get { return GetProperty(MethodBase.GetCurrentMethod()); }
set
{
SetProperty(MethodBase.GetCurrentMethod(), value);
}
}
private string GetProperty(MethodBase method)
{
return _dr[method.Name.Substring(4)].ToString();
}
private void SetProperty(MethodBase method, string value)
{
string methodName = method.Name.Substring(4);
VerifyAccess(methodName , this.GetType().Name);
_dr[methodName] = value;
}
This can be done with indirect value access, e.g. obj.PropA.Value = obj.PropB.Value + 1 -- you can even keep strong typing information. It can be implemented with either attributes or direct-instantiation.
// attribute -- bind later in central spot with annotation application
[MyCustomProp(4)] CustProp<int> Age;
// direct -- explicit binding, could also post-process dynamically
CustProp<int> Age = new CustProp<int>(4, this);
Alternatively, perhaps using a template system such as TT4 may be a viable approach.
However, don't forget "KISS" :-)
I would love for someone to give a better answer for this.
I'm looking for an answer now… best idea I have had would be to define all the properties you want to have be validated as a generic class. For example:
public class Foo {
public String Name {
get{ return _Name.value; }
set{ _Name.value = value; }
}
private Proxy<String> _Name;
static void main(String[] args) {
Foo f = new Foo();
//will go through the logic in Proxy.
f.Name = "test";
String s = f.Name;
}
}
public class Proxy<T> {
public T value {
get {
//logic here
return _this;
} set {
//logic here
_this = value;
}
}
private T _this;
}

Categories

Resources