How to specify defaults for a plugin function in C# - c#

I'm trying to implement a simple plugin system which will allow people to write the following:
[Plugin("A plugin function")]
public static int PluginFunction(int a, int b)
{
return a + b;
}
and then drop the DLL containing this function into a folder where it will be scanned by the application and show up as an available function at runtime. This all works fine, so far so good, the PluginAttribute class is what you would expect, just a description string for the function.
However, I'd like to allow the plugin writer to specify default values for the parameters. This is OK for values which are constant at compile time and then deduced via reflection, but I'd like a way to specify defaults for more complex types which will be created at runtime. Has anyone implemented something similar? The primary goal is to make it simple to implement plugin functions - I'm trying to avoid complex scaffolding but accept that my nice simple system is not going to cut it if I want this feature. I'm also happy to have some complexity in the application code which makes the system appear simple to the plugin writer.
Thanks,
Charlie.
Update:
I'm going with a combination of what's been suggested here, the closest is what Peter O. came up with - here's a version:
[Plugin("A plugin function")]
[Defaults(typeof(AdderDefaults))]
public static int Adder(int a, int b)
{
return a + b;
}
public static class AdderDefaults
{
public static int a { get { return 1; } }
public static int b { get { return 2; } }
}
[Plugin("Another plugin function")]
[Defaults(typeof(TexturizerDefaults))]
public static Bitmap Texturize(Bitmap source, Point offset)
{
return result;
}
public static class TexturizerDefaults
{
// no default for source parameter
public static Point offset { get { return new Point(16, 16); } }
}
This allows parameters to be skipped and specified by name. No compile time checking but that's OK - checking these at runtime is acceptable.

Maybe you can create an attribute which refers to a type
containing default values for the plugin. Example:
[PluginDefaults(typeof(MyPluginDefaults))]
The class MyPluginDefaults could then look like:
public class MyPluginDefaults {
int Parameter1 { // First parameter
get { return 0; } // default value for 'a'
}
int Parameter2 { // Second parameter
get { return 4; } // default value for 'b'
}
// Additional parameters would be called Parameter3, Parameter4, and so on.
}

There are lots of way to do that, the simpliest is to use a simple convention :
[Plugin("A plugin function")]
public static int PluginFunction(int a, int b)
{
return a + b;
}
public static object[] PluginFunctionDefaultArguments()
{
return new [] { 0, 0 };
}
Each time you find a function marked with PluginAttribute search for a function having the same name with the DefaultArguments sufix, no parameters and an object[] return type. Then call it and store the values somewhere. You should also support the default values to be specifed using the dedicated C#/VB syntax (it is found in the DefaultValue member for the parameter)

One way would be to have property Defaults for each of the classes. It returns an object that can be queried for the defaults, for example like this:
object[] pluginFunctionDefaults = FooPlugin.Defaults["PluginFunction"];
(Obviously, you wouldn't have code exactly like this in your application.)
And the declaration of the defaults could look like this:
class FooPlugin
{
static FooPlugin()
{
var bar = new Bar();
Defaults = new DefaultValues()
.Add(() => PluginFunction(42, 13))
.Add(() => AnotherFunction(bar));
}
public static DefaultValues Defaults { get; private set; }
// actual methods of the class
}
Using expressions like this means that the types of the defaults are checked at compile time. The DefaultValues class parses the expressions and stores the parameters. It could look something like this:
class DefaultValues
{
private readonly Dictionary<string, object[]> m_expressions =
new Dictionary<string, object[]>();
public DefaultValues Add<T>(Expression<Func<T>> func)
{
var methodCall = ((MethodCallExpression)func.Body);
var name = methodCall.Method.Name;
var arguments =
methodCall.Arguments
.Select(Evaluate)
.ToArray();
m_expressions.Add(name, arguments);
return this;
}
private static object Evaluate(Expression expression)
{
return Expression.Lambda<Func<object>>(
Expression.Convert(expression, typeof(object)))
.Compile()();
}
public object[] this[string methodName]
{
get { return m_expressions[methodName]; }
}
}

Related

Passing list of defined values as parameter C#

How can I make my method have defined list of values that can be passed. I've seen this in VB.net, but can't find it in C#, and it dosen't look like enum.
class Test
{
List { active, all, completed}
public string get(string a, List b)
{
// some code
}
string a = get("foo", active);
string b = get("foo", all);
}
If enum is called test, I need to pass test.active and I don't want that. I need to pass only active
What you can do is use the using static keyword when you want to use the enum, then you can just use the word you want.
namespace Foo
{
class Test
{
public string get(string a, List b)
{
// some code
}
}
public enum List { active, all, completed}
}
used like
using Foo;
using static Foo.List;
public void Example()
{
var test = new Test();
//Because of "using static Foo.List;" you don't need to use "List.active"
string a = test.get("foo", active);
string b = test.get("foo", all);
}

c# virtual static members

Yeah, I know there aren't any virtual static members in c#, but I have a problem where they would be really helpful and I can't see a good way to proceed.
I've got a standard kind of system where I send packets of data over a communication channel and get back responses. The communication system needs to know how many bytes of response to wait for, and the length of the response is fixed for each command type, so I have this code defined:
public abstract class IPacket
{
public abstract int ReceiveLength { get; }
public abstract byte[] DataToSend();
}
public class Command1 : IPacket
{
public override int ReceiveLength { get { return 3; } }
public Command1() { }
}
public class Command2 : IPacket
{
public override int ReceiveLength { get { return DataObject.FixedLength; } }
public Command2(int x) { }
}
public class Command3 : IPacket
{
static DataHelperObject Helper;
public override int ReceiveLength { get { return Helper.DataLength(); } }
static Command3()
{
Helper = new DataHelperObject();
}
public Command3(really long list of parameters containing many objects that are a pain to set up) { }
}
Notice that in each case, ReceiveLength is a fixed value - sometimes it's a simple constant (3), sometimes it's a static member of some other class (DataObject.FixedLength) and sometimes it's the return value from a member function of a static member (Helper.DataLength()) but it's always a fixed value.
So that's all good, I can write code like this:
void Communicate(IPacket packet)
{
Send(packet.DataToSend());
WaitToReceive(packet.ReceiveLength);
}
and it works perfectly.
But now I would like to output a summary of the packets. I want a table that shows the command name (the class name) and the corresponding ReceiveLength. I want to be able to write this (pseudo)code:
foreach (Class cls in myApp)
{
if (cls.Implements(IPacket))
{
Debug.WriteLine("Class " + cls.Name + " receive length " + cls.ReceiveLength);
}
}
But of course ReceiveLength requires an object.
I don't think I can use attributes here, c# won't let me say:
[PacketParameters(ReceiveLength=Helper.DataLength())]
public class Command3 : IPacket
{
static DataHelperObject Helper;
static Command3()
{
Helper = new DataHelperObject();
}
public Command3(really long list of parameters containing many objects that are a pain to set up) { }
}
because custom attributes are created at compile time (right?), long before the static constructor gets called.
Constructing objects of each type isn't particularly pleasant (pseudocode again):
foreach (Class cls in myApp)
{
IPacket onePacket;
if (cls is Command1)
onePacket = new Command1();
else if (cls is Command2)
onePacket = new Command2(3);
else if (cls is Command3)
{
Generate a bunch of objects that are a pain to create
onePacket = new Command3(those objects);
}
Debug.WriteLine("Class " + cls.Name + " receive length " + onePacket.ReceiveLength);
}
I need ... a virtual static property.
One solution would be to throw all compile-time safety over board and simply use reflection to access your static property like so: http://fczaja.blogspot.ch/2008/07/accessing-static-properties-using-c.html
Alternatively, you could separate out that information into a "PaketSizeManager" type which would simply have either the above-mentioned Dictionary or some switch-case statement plus some neat way to access this information from the outside, as in a public int GetSize(Type t){ .../* use dictionary or switch-case here */... } method. That way you would have encapsulated the size aspect of all your entities into a separate class.
Just make a public static CommandX.Length property, have it return what your ReceiveLength property is now, then have ReceiveLength refer to it. To get the best of both worlds, first you need both worlds.

Creating a non-static version of compiler-based "dictionary" where keys are types

There is a very easy trick which creates a dictionary-like structure where keys are types.
The structure acts like a Dictionary<Type, T?> where keys are Type objects and values are instances of the corresponding types.
This wonderful structure is as fast as just a variable or array since the "lookup" is only done once by the compiler/JITter and the proper value reference is compiled into your program.
public static class MyDict<T> {
public static T Value { get; set; }
}
You can work with that structure like this:
MyDict<string>.Value = MyDict<int>.Value.ToString();
The problem is that this "dictionary" is global. The only way to create different dictionaries is to create different classes.
How can create a similar (fastest "lookup", no boxing) non-static structure? (Without code generation.)
Simply said: I want to have multiple Dictionary<Type, object>-like objects without lookup costs, casting and boxing.
Here's an approach that extends the method described in the question:
public class TypeDict
{
public T Get<T>()
{
return MyDict<T>.Values[this];
}
public void Set<T>(T value)
{
MyDict<T>.Values[this] = value;
}
private static class MyDict<T>
{
public static Dictionary<TypeDict, T> Values { get; private set; }
static MyDict()
{
Values = new Dictionary<TypeDict, T>();
}
}
}
Now we can use the TypeDict like this:
void X()
{
var a = new TypeDict();
var b = new TypeDict();
a.Set<int>(1);
a.Set<double>(3.14);
a.Set("Hello, world!");
//Note that type inference allows us to omit the type argument
b.Set(10);
b.Set(31.4);
b.Set("Hello, world, times ten!");
Console.WriteLine(a.Get<int>());
Console.WriteLine(a.Get<double>());
Console.WriteLine(a.Get<string>());
Console.WriteLine();
Console.WriteLine(b.Get<int>());
Console.WriteLine(b.Get<double>());
Console.WriteLine(b.Get<string>());
}
Ark-kun is using generics to essentially generate unique types at compile time. With a generic type, any static members are unique to that specific closed generic type. This way it's processed as fast as a standard static member lookup.
The above usage is equivalent to something like this:
public static class MyDict_String
{
public static string Value { get; set; }
}
public static class MyDict_Int32
{
public static int Value { get; set; }
}
MyDict_String.Value = MyDict_Int32.Value.ToString();
AFAIK, types are "static" (in that you can't define more than one that way) so I don't know of a way to cheat around this and maintain the same performance of a statically compiled member lookup.
Your best bet otherwise (I think) is to create a generic instance type that wraps its own dictionary that uses System.Type for its keys and System.Object for its values to which you have to perform boxing/casting when inserting/retrieving values.
EDIT: Here's a simple implementation wrapping a dictionary:
public class MyTypedDict
{
private Dictionary<Type, object> Values = new Dictionary<Type, object>();
public T Get<T>()
{
object untypedValue;
if (Values.TryGetValue(typeof(T), out untypedValue))
return (T)untypedValue;
return default(T);
}
public void Set<T>(T value)
{
Values[typeof(T)] = value;
}
}
Thinking about it more, it might be possible to achieve a more property-like syntax using an ExpandoObject (http://msdn.microsoft.com/en-us/library/system.dynamic.expandoobject.aspx) through some tomfoolery, but I feel like this would be pretty abusive and I can only assume terribly prone to runtime errors. (plus it would afford you nothing at compile time)
EDITx2: If you really want to have different sets of values, you could nest it within another generic type:
public static class ValueSets<T>
{
public static class MyDict<U>
{
public static U Value { get; set; }
}
}
With usage like:
ValueSets<int>.MyDict<string>.Value = "Hello ";
ValueSets<bool>.MyDict<string>.Value = "World!";
string helloworld = ValueSets<int>.MyDict<string>.Value + ValueSets<bool>.MyDict<string>.Value;
Console.WriteLine(helloworld);//Hello World!
But then the initial type int and bool in this case become "magical" and without meaning, plus you would need to provide a unique type per distinct set of values you'd like to use. Plus you could not pass it around and modify as an instance variable, rather it'd be statically accessible (so long as you have access to use the type T). So perhaps you could declare minimally visible types that are named with meaning and use those:
internal class MyFirstWords {}
internal class MySecondWords {}
ValueSets<MyFirstWords>.MyDict<string>.Value = "Hello ";
ValueSets<MySecondWords>.MyDict<string>.Value = "World!";
string helloworld = ValueSets<MyFirstWords>.MyDict<string>.Value + ValueSets<MySecondWords>.MyDict<string>.Value;
Console.WriteLine(helloworld);//Hello World!
Regardless, I think this is quite wacky and I wouldn't recommend it.
A more complicated version. Don't know if it's closer:
Define a generic dictionary:
public class MyDictionary<T>
{
Dictionary<string, T> dict;
public MyDictionary()
{
dict = new Dictionary<string, T>();
}
public T this[string name]
{
get
{
if (dict.ContainsKey(name))
return dict[name];
else
return default(T);//or throw
}
set
{
dict[name] = value;
}
}
}
Then a repository to store those dictionaries:
public class MyRepository
{
List<object> repo;
public MyRepository()
{
repo = new List<object>();
}
public void Add<T>(string name, T value)
{
if (!repo.OfType<MyDictionary<T>>().Any())
repo.Add(new MyDictionary<T>());
var dict = repo.OfType<MyDictionary<T>>().FirstOrDefault();
dict[name] = value;
}
public T GetValue<T>(string name)
{
if (!repo.OfType<MyDictionary<T>>().Any())
return default(T);//or throw
else
{
var dict = repo.OfType<MyDictionary<T>>().FirstOrDefault();
return dict[name];
}
}
}
And finally you may use this repository:
MyRepository repo = new MyRepository();
repo.Add("A", 1);
repo.Add("B", 1);
int i = repo.GetValue<int>("A") + repo.GetValue<int>("B");
In this example, there is MyDictionary<T> boxing to object is left.
From the other side, if your are working with some certain types you may not use thie repository class at all. But utilize separate dictionaties.
MyDictionary<int> intDict = new MyDictionary<int>();
intDict["A"] = 1;
intDict["B"] = 2;
int i = intDict["A"] + intDict["B"];
However it's the same as working with
Dictionary<string, int> intDict = new Dictionary<string, int>();
So the MyRepository class may be edited to use Dictionary<string, T> instead of MyDictionary<T>.
#Konstantin's answer made me remember that there is actually a very fast lookup method - array indexing. This crude PoC code shows a variant of the required structure.
public class TypeDictionary {
static int _maxId = 0;
int _id;
static class Store<T>{
internal static List<T> Values = new List<T>();
}
public TypeDictionary() {
_id = _maxId++;
}
public T GetValue<T>() {
return Store<T>.Values[_id];
}
public void SetValue<T>(T value) {
while(Store<T>.Values.Count < _id) {
Store<T>.Values.Add(default(T));
}
Store<T>.Values[_id] = value;
}
}
This code can be used as follows:
var dict1 = new TypeDictionary();
dict1.SetValue("my string");
string result = dict1.GetValue<string>();
The problem with this solution is it's memory usage caused by the repository being not sparse. This also makes first time value setting more expensive.
Try this:
public class MyDictionary
{
List<object> values;
public MyDictionary()
{
values = new List<object>();
}
public T GetValue<T>()
{
return values.OfType<T>().FirstOrDefault();
}
public bool Add<T>(T value)
{
if (values.OfType<T>().Any())
return false;
else
{
values.Add(value);
return true;
}
}
}
and use it:
var md = new MyDictionary();
md.Add("!!!");
string s = md.GetValue<string>();
This class may store up to one value of type T. But there could corner cases with derived classes and interfaces I guess. You may check, if it suits your need, and probably modify it as you need, if it's close to what you need in general.
What you are looking for is impossible in C#. The language does not support a container that could store multiple objects of different types yet provides a look up method that does not involve casting, boxing or unboxing. You could accomplish something like this with macros in C++, or via a language like javascript where the structure of types can be changed at run-time.
The usage case you are describing fits quite closely with the purpose for which ConditionalWeakTable<TKey,TValue> was added to .NET 4.0. For the purpose you describe, you would include such a table in a static generic class, and then for every class object that's supposed to contain a reference to an item of a particular type you would store into that type's table a reference to object that's supposed to contain the item along with either a reference to the item, or else a reference to a simple item-holder object (note that entries in ConditionalWeakTable will evaporate when an object ceases to exist, but are otherwise immutable, so if you want a mutable association you'll need to create an object to hold it).
Building on #phoog's example with #supercat's suggestion
public class TypeDict
{
public T Get<T>() where T : class
{
T value;
InnerDict<T>.Values.TryGetValue(this, out value);
return value;
}
public void Set<T>(T value) where T : class
{
var cwt = InnerDict<T>.Values;
// lock+remove+add https://github.com/dotnet/coreclr/issues/4545
lock (cwt)
{
cwt.Remove(this);
cwt.Add(this, value);
}
}
private static class InnerDict<T> where T : class
{
public static ConditionalWeakTable<TypeDict, T> Values { get; private set; }
static InnerDict()
{
Values = new ConditionalWeakTable<TypeDict, T>();
}
}
}

Read property from the same class

In C# if I have this in a class:
public int SomeNumber
{
get { return 6; }
}
How can I read (get) that number from a function in the same class if the function receives a variable with the same name? Example:
public bool SomeFunction(int SomeNumber)
{
check if SomeNumber (the one passed to this function) == SomeNumber (the one from the public int)
}
You would simply invoke the property get in the method:
public void MyMethod()
{
var someNum = SomeNumber; // basically, var somNum = this.SomeNumber;
}
EDIT: To clarify with OP's edit:
public void MyMethod(int someNumber)
// Change the naming of your parameter so it doesnt clash with the property
{
if(someNumber == SomeNumber)
// Do Stuff
}
Same as if it were a field:
public void SomeOtherFunction()
{
var x = SomeNumber;
}
Although the other suggestions do work well (and adhere to easier to read/maintain code), they don't directly answer your question. Given a class
public class SomeClass
{
public int SomeNumber { get { return 6; } }
...
And a function with a parameter passed in
public void SomeMethod(int SomeNumber)
{
// Your code here...
You can access the passed in parameter and property like so:
if (SomeNumber > this.SomeNumber)
{
// Your results here
The distinction is that if you refer to just the variable name, it will use the variable from the same scope, i.e. the passed in variable. If you specify use "this." then you always get the class member.
Note: This does not work with Static classes, as there is no instance of the class. (Can't use "this.whatever") and you will be stuck. There are many coding Standards out there and some of them states that it is best practice to use the form "myVariable" for method parameters, "MyVariable" for property names, and _myVariable for property backing stores, to easily distinguish between them in your code.
public class FavoriteNumber
{
public int SomeNumber
{
get { return 6; }
}
Public int Twelve()
{
return SomeNumber*2;
}
}
Please run this code and you will get it.. Use this operator to refer the class level variale.
public void CheckNumber(int SomeNumber)
{
Console.WriteLine(SomeNumber);
Console.WriteLine(this.SomeNumber);
}

.Net interface for a known return type, but unknown type/number of parameters

Is there a way to specify in an interface a known return type, but unknown number/type of parameters.
The reason I am asking is that I am using Windows Azure Table Storage and each table will have different Partition and Row keys with different input values.
I am creating a ITableOperations interface the code will be something like:
interface ITableOperations<T>
where T : Azure.AzureTableEntity
{
// Key specification
string PartitionKey(/* ? What should go here */);
// Key specification
string RowKey(/* ? What should go here */);
}
And the item table... For another table, the input params would be different
public class ScheduledItem : ITableOperations<ScheduledPostEntity>
{
public string PartitionKey(Guid userGuid)
{
return userGuid.ToString();
}
public string RowKey(DateTime dateScheduled)
{
return dateScheduled.ReverseTicks();
}
}
You could try having a very generic interface. For example:
interface ITableOperations<T, P, R>
where T : Azure.AzureTableEntity
{
string PartitionKey(P partitionKey);
string RowKey(R rowKey);
}
Then your implementation could be:
public class ScheduledItem : ITableOperations<ScheduledPostEntity, Guid, DateTime>
{
public string PartitionKey(Guid userGuid)
{
return userGuid.ToString();
}
public string RowKey(DateTime dateScheduled)
{
return dateScheduled.ReverseTicks();
}
}
EDIT:
Looking at some of your comments since I originally wrote this answer, you could come at it from a different angle. The PartitionKey and RowKey won't change on your object once it has been created, so I'd almost take these particular functions out of this class and move it to the constructors of the classes that inherit from AzureTableEntity. e.g.
public class ScheduledPostEntity : Azure.AzureTableEntity
{
private Guid _userGuid;
private DateTime _dateScheduled;
public ScheduledPostEntity()
{
// Needed for deserialisation from Azure Table Storage
}
public ScheduledPostEntity(Guid userGuid, DateTime dateScheduled)
{
_userGuid = userGuid;
_dateScheduled = dateScheduled;
}
public string PartitionKey
{
get { return _userGuid.ToString(); }
set { _userGuid = Guid.Parse(value); }
}
public string RowKey
{
get { return _dateScheduled.ReverseTicks(); }
set { _dateScheduled = value.FromReverseTicks(); }
}
// These are functions to avoid them being saved as additional properties
// in Azure Table Storage. Sometimes you can get away with them being
// read only properties, but it depends on the type.
public DateTime DateScheduled()
{
return _dateScheduled;
}
public Guid UserGuid()
{
return _userGuid;
}
}
This has the advantage that whenever you create on of these objects, you know minimum requirements to save the object. It also stops you from messing with things that will change your PK and RK.
C# supports multiple parameter in the form of an array by using the params keyword.
You could do this:
interface ITableOperations<T>
where T : Azure.AzureTableEntity
{
// Key specification
string PartitionKey(params object[] data);
// Key specification
string RowKey(params object[] data);
}
If you already know the alternatives of parameters, then you can use overload.
Lets say you have a method that can either receive a string or a Guid or both, you could do this:
string PartitionKey(Guid guid);
string PartitionKey(string str);
string PartitionKey(Guid guid, string str);
If you are using C# 4, then you can use optional parameters:
string PartitionKey(Guid guid = default(Guid), string str = null);
You could define one parameter, which would be an array. This array would contain name/value pairs and could have as many as you need. I think this would give you the flexibility you're looking for.
This still won't show you the proper list of parameters for DoStuff (you'll just see params object[]) but it's about as flexible as you'll get. Note that I've implemented the method explicitly in the implementing class so you don't see it in Intellisense if "foo" is declared as a Foo rather than an IFoo.
class Program
{
static void Main(string[] args)
{
IFoo foo = new Foo();
foo.DoStuff(Guid.NewGuid());
}
}
public interface IFoo
{
void DoStuff(params object[] args);
}
public class Foo : IFoo
{
public void DoStuff(Guid arg)
{
}
void IFoo.DoStuff(params object[] args)
{
if (args.Length != 1) throw new ArgumentException("args");
if (args[0].GetType() != typeof(Guid)) throw new ArgumentException("args");
DoStuff((Guid)args[0]);
}
}

Categories