Define the interface that all your plugins should implement:
public interface IPlugin { string Name { get; } string Author { get; } string Description { get; } void Init(); }
And then use Dictionary<Type, IPlugIn> .
Typically, an interface is declared in a separate dll (for example, "MyCompany.MyProject.PlugIns.Contracts.dll").
EDIT: Well, I think I know what you mean now.
The trick is to have a common class between Field and UsernameField using the common Set method. The fact that Field not generic makes all field types assignable to it. This would not be the case if it were declared as Field<T> .
public abstract class Field { } public abstract class GenericField<T> : Field { public void Set(DynamicObject obj, T value) { obj[this.GetType()] = value; } } public class UsernameField : GenericField<string> { #region Singleton Pattern public static readonly UsernameField Instance = new UsernameField(); private UsernameField() { } #endregion }
Since we need to call GetType in the Set method, we cannot declare it as static . Therefore, I used the singleton pattern.
Now we can set the field in a safe way:
UsernameField.Instance.Set(obj, "Joe");
APPENDIX 1:
Since fields are now single, you can use fields as a dictionary key instead of your type.
public class DynamicObject : IDictionary<Field, object> { }
And Set will become:
public void Set(DynamicObject obj, T value) { obj[this] = value; }
APPENDIX 2:
You can also define DynamicObject as follows:
public class DynamicObject : Dictionary<Field, object> { public void Set<T>(GenericField<T> field, T value) { this[field] = value; } }
Now you can set these values:
obj.Set(UsernameField.Instance, "Sue");
It is a safer type and seems more natural. The Set method in GenericField deprecated.