I'm writing an application in C#, which supports plugins. Each plugin has to introduce itself, such that application can prepare appropriate environment for it. The current info object looks more less like this:
class FilterInfo
{
public InputInfo[] inputs;
public OutputInfo[] outputs;
bool IsConfigurable;
bool IsPlayable;
string TypeName;
}
This structure will surely expand in future (however, I guess, that not much, it'll maybe double its size). I'm currently thinking on how to implement such info class properly.
In C++ I would do it the following way (I'll strip the class to one field to make the examples more readable):
class FilterInfo
{
private:
std::vector<const InputInfo> inputs;
public:
std::vector<const InputInfo> & GetInputs()
{
return inputs;
}
const std::vector<const InputInfo> & GetInputs() const
{
return inputs;
}
}
Now, the plugin would instantiate a FilterInfo class, fill-in its fields and then return const FilterInfo on request, such that noone may change contents of the info (well, noone should).
In C#, I can only imagine the following "safe" solution:
public interface IInputInfo
{
bool SomeData
{
get;
}
}
public class InputInfo : IInputInfo
{
private bool someData;
public bool SomeData
{
get
{
return someData;
}
set
{
someData = value;
}
}
public bool IInputInfo.SomeData
{
get
{
return someData;
}
}
}
public interface IFilterInfo
{
ReadOnlyCollection<IInputInfo> Inputs
{
get;
}
}
public class FilterInfo : IFilterInfo
{
private InputInfo[] inputs;
public InputInfo[] Inputs
{
get
{
return inputs;
}
set
{
inputs = value;
}
}
public ReadOnlyCollection<IInputInfo> IFilterInfo.Inputs
{
return inputs;
}
}
The plugin will, of course, return IFilterInfo instead of FilterInfo, such that the data is readonly (OK, I know about reflection, the matter is to notify the user, that the data should not be changed). However, this solution looks very clumsy to me - especially when compared to compact version I cited earlier.
Another solution may to be create FilterInfo only with getters, but it would require passing the data into it in some way and probably would end up with a huge constructor with lots of parameters.
Edit: Another solution is to create a struct and return its copy during every request. However, arrays are copied by reference, so I would have to copy them manually each time.
Yet another one is to construct the FilterInfo from the scratch each time anyone requests it, eg.
public FilterInfo Info
{
get
{
return new FilterInfo()
{
IsConfigurable = true,
IsPlayable = false,
Inputs = new[]
{
new InputInfo()
{
// (...)
}
}
}
}
}
Is there an elegant way to solve this problem?
I think you got it almost right the first time:
Define a public IFilterInfo interface in the pluggable assembly that only allows reading.
Implement the interface in a FilterInfo class in the plugin assembly that has internal setters on its properties.
Have a method return a new instance of the FilterInfo class upon request. Convention suggests to use a method instead of a property in cases where a new instance is constructed each time. (If you insist on using a property you could store the instance once it has been constructed and return it through the property)
Example:
In the pluggable assembly:
public interface IFilterInfo {
bool IsPlayable { get; }
bool IsConfigurable { get; }
}
In the plugin assembly:
internal class FilterInfo : IFilterInfo {
public bool IsPlayable { get; internal set; }
public bool IsConfigurable { get; internal set; }
}
public IFilterInfo GetFilterInfo() {
return new FilterInfo() { IsPlayable = true, IsConfigurable = false };
}
Internal setters and a read-only interface should be enough to ensure that the properties aren't modified outside the plugin assembly.
What about setting the setters to private or protected.
public class FilterInfo
{
public InputInfo[] inputs { get; private set; }
public OutputInfo[] outputs { get; private set; };
bool IsConfigurable;
bool IsPlayable;
string TypeName;
public void SetInputs(...)
{
InputInfo[] allInputs;
//do stuff
inputs = AllInput;
}
public void SetOutputs(...)
{
OutputInfo[] allOutputs;
//do stuff
outputs = AllOutput;
}
}
You would be able to have internal methods to set the data or go protected and allow modifying the objects through inheritance.
UPDATE
What about using the internal accessor for the setter. This way nothing will be able to access the setter unless it is declared in the InternalsVisibleTo assembly level attribute, which would be defined in the assembly containing FilterInfo.
The following post gives a good explanation on how to do this using the internal keyword.
Internal Description
UPDATE
Another solution may to be create FilterInfo only with getters, but it would require passing the data into it in some way and probably would end up with a huge constructor with lots of parameters.
According to this the only issue with not having a getter is that you still need to pass in data. The original solution allows this to happen. I guess I might be a little confused. If the plugin is able to change the information in this API which is by reference I am guessing. Then if the application is referencing the same assembly, it too would have the same accessors provided to the plugin. It seems that short of setting the setters to internal and allowing access through attributes would be the only way to achieve that type of functionality. But that wont work in your case because you do not know the assemblies that are referencing your API.
I don't quite sure about what you really want, but it seems the builder pattern is good for this case.
First, the setter or constructor can be marked internal, means that only the assembly can access the constructor or setter. Leave the getter public, it is needed, isn't it?
Then your builder class (assume you are using the constructor injection):
public class FilterInfoBuilder{
public FilterInfoBuilder(InputInfo[] inputInfo){
this.inputInfo = inputInfo;
}
private InputInfo[] inputInfo;
public FilterInfo Create(){
FilterInfo filterInfo = new FilterInfo(inputInfo);
return filterInfo;
}
}
Maybe I misunderstand your requirement though.
EDIT
You can tweak the builder as a dynamic setter though. Now consider using internal setter instead of internal constructor.
public class FilterInfoBuilder{
public FilterInfoBuilder(InputInfo[] inputInfo){
filterInfo = new FilterInfo();
filterInfo.InputInfo = inputInfo;
}
private FilterInfo filterInfo;
public FilterInfo FilterInfo{
get{
return filterInfo;
}
}
public void ChangeInputInfo(InputInfo[] inputInfo){
filterInfo.InputInfo = inputInfo;
}
}
You can use FilterInfoBuilder.FilterInfo to access the FilterInfo class. To modify it, you can create internal methods inside the builder class.
I don't really sure about the solution though, as I haven't found the design in any documented source.
More EDIT
I have another design, only if you can separate the interface between assemblies and make sure the application access the interface and not the class.
example:
public interface IInputInfoSetable{
public InputInfo[] InputInfo{
set;
}
}
public interface IFilterInfo{
public InputInfo[] InputInfo{
get;
}
}
public class FilterInfo: IFilterInfo, IInputInfoSetable{
// implement explicitly both of the interface.
}
Related
I have this class called BluetoothDeviceInfo from 32feet library to handle, obviously, Bluetooth related stuff.
I have created my program and it worked. However, I need to add some information to a "more complete", lets say, class which also carries GPS information.
So what I did was to created a new class MyDeviceInfo and derive it from BluetoothDeviceInfo as the code below.
Base* (which I don't have control on)
namespace InTheHand.Net.Sockets
{
public class BluetoothDeviceInfo : IComparable
{
public BluetoothDeviceInfo(BluetoothAddress address);
public bool Authenticated { get; }
public ClassOfDevice ClassOfDevice { get; }
public bool Connected { get; }
public BluetoothAddress DeviceAddress { get; }
public string DeviceName { get; set; }
.
.
.
Derive*
public class MyDeviceInfo : BluetoothDeviceInfo
{
private bool gpsSignal;
public MyDeviceInfo(BluetoothAddress address) : base(address)
{
gpsSignal = false;
}
#region Properties
public bool GpsSignal { get { return gpsSignal; } set { gpsSignal = value;}}
}
And I substituted all my BluetoothDeviceInfo types in my code with MyDeviceInfo types.
Everything seems working except this part.
This particular method called Client.DiscoverDevice() returns a list of Bluetooth devices available in the type BluetoothDeviceInfo. And since this is of a type base class, it doesn't make sense that I would cast it to a variable of my derive class MyDeviceInfo and I can't get past this point since I need the list of devices. Even though sounding wrong I tried to cast it using this code (which obviously didn't work)
IEnumerable<MyDeviceInfo> _discoveredCsaDevices = (IEnumerable<MyDeviceInfo>)cli.DiscoverDevices().Where(d => (d.DeviceName.StartsWith(...
Since this logic doesn't fit into inheritance I thought of composition. However, this isn't quite fit the composition line of thought such as object Bird can have flying functionality of type Airplane but not the whole lot cuz I actually need my driven class include all the functionality of BluetoothDeviceInfo.
I want to understand the big picture here and what would be approach to do such a thing.
Will be happy to hear you thoughts and guides on this.
Cheers
Try this:
IEnumerable<MyDeviceInfo> _discoveredCsaDevices = (cli.DiscoverDevices().Where(d => (d.DeviceName.StartsWith(...).Select (b => new MyDeviceInfo(b.DeviceAddress)).ToList();
You may need to provide a MyDeviceInfo constructor that takes a BluetoothDeviceInfo and copies all the properties.
Update
The code then becomes:
public class MyDeviceInfo : BluetoothDeviceInfo
{
private bool gpsSignal;
MyDeviceInfo(BluetoothDeviceInfo btInfo)
{
this.Authenticated = btInfo.Authenticated;
this.ClassOfDevice = btInfo.ClassOfDevice;
this.Connected = btInfo.Connected;
this.DeviceAddress = btInfo.DeviceAddress;
this.DeviceName = btInfo.DeviceName;
}
public MyDeviceInfo(string address) : base(address)
{
gpsSignal = false;
}
public bool GpsSignal { get { return gpsSignal; } set { gpsSignal = value;}}
}
And you use it like this:
IEnumerable<MyDeviceInfo> _discoveredCsaDevices = (cli.DiscoverDevices().Where(d => (d.DeviceName.StartsWith(...).Select (b => new MyDeviceInfo(b)).ToList();
Application note.
To the extent that inheritance works, use that. See Ned Stoyanov's answer. My answer below should only be used if the library class is sealed.
Problem #1 - Library class was sealed and wasn't dependent on an interface, therefore I cannot substitute it with my own class.
Solution: Make an interface anyway.
public interface IMyDeviceInfo : IComparable
{
BluetoothDeviceInfo(BluetoothAddress address);
bool Authenticated { get; }
ClassOfDevice ClassOfDevice { get; }
bool Connected { get; }
BluetoothAddress DeviceAddress { get; }
string DeviceName { get; set; }
...
}
Problem #2 - How can I stuff the library class under my interface?
Solution: Make an adapter.
public class DeviceInfoAdapter : IMyDeviceInfo
{
private BluetoothDeviceInfo m_theRealStuff;
// Allow yourself to bypass the abstraction to
// get down to the real object, because it may
// just be unavoidable in some cases.
// You may also mark it [Obsolete] or comment it out
// until you encounter a real need for it.
internal BluetoothDeviceInfo TheRealStuff
{
get { return m_theRealStuff; }
}
// Constructor. If the real stuff has been created by someone else.
public DeviceInfoAdapter(BluetoothDeviceInfo theRealStuff)
{
m_theRealStuff = theRealStuff;
}
// Constructor. A knock-off copy of the real stuff constructor.
public DeviceInfoAdapter(BluetoothAddress address)
{
m_theRealStuff = new BluetoothDeviceInfo(address);
}
// Imitate all properties and methods on the real stuff.
public bool Authenticated
{
get
{
return m_theRealStuff.Authenticated;
}
}
// ...
// Basically, for every publicly-accessible method or property,
// you just call the real stuff.
}
Problem #3 - How do I add extra properties to it?
Solution: Make a decorator.
public interface IMyDeviceInfoExtra : IMyDeviceInfo
{
bool GpsSignal { get; set; }
}
public class MyDeviceInfoWithGps : IMyDeviceInfoExtra
{
private IMyDeviceInfo m_theRealStuff;
private bool m_gpsSignal;
public MyDeviceInfoWithGps(IMyDeviceInfo theRealStuff)
{
m_theRealStuff = theRealStuff;
}
// the same thing again ... lots of code duplications
// The only new member here
public bool GpsSignal
{
get { return m_gpsSignal; }
set { m_gpsSignal = value; }
}
}
I have a lot of similar classes generated by svcutil from some external WSDL file. Any class has a Header property and string property which named class name + "1".
For instance, I have classes: SimpleRequest that has Header property and SimpleRequest1 property.
Another one is ComplexRequest that has Header property and ComplexRequest1 property.
So, I want to create a common interface for such classes. So, basically I can define something like that:
interface ISomeRequestClass {
string Header;
// here is some definition for `class name + "1"` properties...
}
Is it possible to define such member in interface?
Here is post edit goes...
Here is sample of generated class:
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
[System.ServiceModel.MessageContractAttribute(IsWrapped=false)]
public partial class SimpleRequest
{
public string Header;
[System.ServiceModel.MessageBodyMemberAttribute(Name="SimpleRequest", Namespace="data", Order=0)]
public SimpleRequestMsg SimpleRequest1;
public SimpleRequest()
{
}
public SimpleRequest(string Header, SimpleRequestMsg SimpleRequest1)
{
this.Header = Header;
this.SimpleRequest1 = SimpleRequest1;
}
}
POST EDIT 2
I changed definition of this annoying +1 property to represent real actual picture. It's all has different class types. So how can I pull it out to common interface?
POST EDIT 3
Here is coupled question that could bring more clarify.
EDIT (after seeing your code sample): Technically speaking, your code does not have a Header property, it has a Header field. This is an important difference, since you cannot specify fields in an interface. However, using the method described below, you can add properties to your classes that return the field values.
Is it possible to define such member in interface?
No, interface names cannot be dynamic. Anyway, such an interface would not be very useful. If you had an instance of class ISomeRequestClass, what name would you use to access that property?
You can, however, use explicit interface implementation:
interface ISomeRequestClass {
string Header { get; set; }
string ClassName1 { get; set; }
}
class SomeClass : ISomeRequestClass {
string Header { ... }
string SomeClass1 { ... }
// new: explicit interface implementation
string ISomeRequestClass.ClassName1 {
get { return SomeClass1; }
set { SomeClass1 = value; }
}
}
You could define your interface more generally:
interface ISomeRequestClass {
string HeaderProp {get; set;}
string Prop {get; set;}
}
And your concrete classes could be extended (in an extra code file) by mapping interface members to class fields like so:
public partial class SimpleRequest : ISomeRequestClass
{
public string HeaderProp
{
get
{
return Header;
}
set
{
Header = value;
}
}
public string Prop
{
get
{
return SimpleRequest1;
}
set
{
SimpleRequest1= value;
}
}
}
Putting aside for a moment the naming of your classes and properties.
If you're looking to create an interface with a property relevant to your specific +1 type, you have a couple of options.
Use a base class for your +1's
If both of your +1 classes inherit from the same base class you can use this in your interface definition:
public interface IFoo
{
[...]
PlusOneBaseType MyPlusOneObject{get;set;}
}
Create a generic property on your interface
This method allows you to specify the type for the +1 property as a generic parameter:
public interface IFoo<TPlusOneType>
{
[...]
TPlusOneType MyPlusOneObject{get;set;}
}
Which you might use like:
public class SimpleRequest : IFoo<SimpleRequest1>
{
[...]
}
Update
Given that your classes are partial classes, you could always create a second (non machine generated) version of the partial class that impliments your interface.
You mentioned svcutil so I assume you are using these classes as WCF DataContracts?
If that is the case then you could make use the name property of DataMemberAttribute.
interface IRequest
{
string Header { get; set; }
string Request1 { get; set; }
}
[DataContract]
class SimpleRequest : IRequest
{
[DataMember]
public string Header { get; set; }
[DataMember(Name="SimpleRequest1"]
public string Request1 { get; set; }
}
[DataContract]
class ComplexRequest : IRequest
{
[DataMember]
public string Header { get; set; }
[DataMember(Name="ComplexRequest1"]
public string Request1 { get; set; }
}
If you are concerned giving yourself more work when you regenerate the code at some point in the future, then I recommend you write a PowerShell script to do this transformation automatically. After all svcutil is just a script written by some guy at Microsoft. It is not magic or "correct" or "standard". Your script can make a call to scvutil and then make a few quick changes to the resulting file.
EDIT (After seeing your edit)
You are already using MessageBodyMemberAttribute's Name property so just change this:
public string SimpleRequest1;
To
public string Request1;
Do you actually need these classes to have a common interface? I'd be tempted to instead create a wrapper interface (or just a concrete class) which could then use reflection to access the fields in question:
// TODO: Make this class implement an appropriate new interface if you want
// to, for mocking purposes.
public sealed class RequestWrapper<TRequest, TMessage>
{
private static readonly FieldInfo headerField;
private static readonly FieldInfo messageField;
static RequestWrapper()
{
// TODO: Validation
headerField = typeof(TRequest).GetField("Header");
messageField = typeof(TRequest).GetField(typeof(TRequest).Name + "1");
}
private readonly TRequest;
public RequestWrapper(TRequest request)
{
this.request = request;
}
public string Header
{
get { return (string) headerField.GetValue(request); }
set { headerField.SetValue(request, value); }
}
public TMessage Message
{
get { return (TMessage) messageField.GetValue(request); }
get { messageField.SetValue(request, value); }
}
}
You could use expression trees to build delegates for this if the reflection proves too slow, but I'd stick to a simple solution to start with.
The advantage of this is that you only need to write this code once - but it does mean creating a wrapper around the real request objects, which the partial class answers don't.
Suppose I have a the following code:
Container.cs
public class Container
{
public readonly string IdType;
public Container( string aIdType )
{
IdType = aIdType;
}
}
SuperContainerA .cs
public class SuperContainerA : Container
{
public SuperContainerA( /*x parameters*/ ) : base("A") {}
}
SuperContainerB.cs
public class SuperContainerB : Container
{
public SuperContainerB( /*y parameters*/ ) : base("B") {}
}
SuperContainerToTheInfinityAndBeyond.cs
public class SuperContainerB : Container
{
public SuperContainerB( /*y parameters*/ ) : base("It's Over 9000!") {}
}
Based on that, what I'm trying to retrieve is the "A" and "B" that are being sent to the TypeId from the constructor.
The catch here is... I need to retrieve those values during the initialization of the program, before creating an instance of those classes, so I thought that using reflection is my best bet here. (Note: Creating an instance of the classes to retrieve the value would be valid if the number of parameters for each constructor would be the same, but they can change. :()
Is it possible to use reflection to check the literals of my source code and/or Assemblies? (If I can see something like the source code, then I can use Regex to get the value.)(Note: Including the sources as resource files to my program is not an option :P)
I'm thinking of declaring constants to hold the value and force an naming rule on then, so that I could use reflection later to grab then back. Something like ...
public class SuperContainerA
{
public const string ctIdType = "A";
}
public class SuperContainerB
{
public const string ctIdType = "B";
}
... But I'm not sure if this is the best approach to this problem, since I won't have anything to help me check if these consts have been declared and if they got the proper name during compile time.
Actually, if the language had some kind of static inheritance, this would help a lot in this situation, but I hear some programmers complaing that static inheritance is more of an head ache than a cure.
Anyway, I'm searching for alternatives. Any idea is welcome.
Attributes to the rescue!
public class IdTypeAttribute: Attribute
{
public string IdType { get; private set; }
public IdTypeAttribute(string idType)
{
IdType = idType;
}
}
[IdType("B")]
public class SuperContainerB: Container
{
// whatever you like...
}
You can then access the Attribute via reflection. Easy enough to do...
var type = typeof(SuperContainerB);
var attribute = (IdTypeAttribute)type.GetCustomAttributes(
typeof(IdTypeAttribute), false)[0];
var idType = attribute.IdType;
Why not simply use the concrete type to look up the string value that you seem to want associated with it?
public class SuperA : Container
{
public string IdType { get { return IdTypeFactory.Get( GetType() ); } }
}
public static class IdTypeFactory
{
public static string Get( Type containerType ) { ... }
}
The primary benefit of this solution would be to gather all your string literals in one central location. Alternatively, go with the abstract super class.
In my current project I need to be able to have both editable and read-only versions of classes. So that when the classes are displayed in a List or PropertGrid the user is not able to edit objects they should not be allowed to.
To do this I'm following the design pattern shown in the diagram below. I start with a read-only interface (IWidget), and then create an edtiable class which implements this interface (Widget). Next I create a read-only class (ReadOnlyWidget) which simply wraps the mutable class and also implements the read only interface.
I'm following this pattern for a number of different unrelated types. But now I want to add a search function to my program, which can generate results that include any variety of types including both mutable and immutable versions. So now I want to add another set of interfaces (IItem, IMutableItem) that define properties which apply to all types. So IItem defines a set of generic immutable properties, and IMutableItem defines the same properties but editable. In the end a search will return a collection of IItems, which can then later be cast to more specific types if needed.
Yet, I'm not sure if I'm setting up the relationships to IMutable and IItem correctly. Right now I have each of the interfaces (IWidget, IDooHickey) inheriting from IItem, and then the mutable classes (Widget, DooHickey) in addition also implement IMutableItem.
Alternatively, I was also thinking I could then set IMutableItem to inherit from IItem, which would hide its read-only properties with new properties that have both get and set accessors. Then the mutable classes would implement IMutableItem, and the read-only classes would implement IItem.
I'd appreciate any suggestions or criticisms regarding any of this.
Class Diagram
Code
public interface IItem
{
string ItemName { get; }
}
public interface IMutableItem
{
string ItemName { get; set; }
}
public interface IWidget:IItem
{
void Wiggle();
}
public abstract class Widget : IWidget, IMutableItem
{
public string ItemName
{
get;
set;
}
public void Wiggle()
{
//wiggle a little
}
}
public class ReadOnlyWidget : IWidget
{
private Widget _widget;
public ReadOnlyWidget(Widget widget)
{
this._widget = widget;
}
public void Wiggle()
{
_widget.Wiggle();
}
public string ItemName
{
get {return _widget.ItemName; }
}
}
public interface IDoohickey:IItem
{
void DoSomthing();
}
public abstract class Doohickey : IDoohickey, IMutableItem
{
public void DoSomthing()
{
//work it, work it
}
public string ItemName
{
get;
set;
}
}
public class ReadOnlyDoohickey : IDoohickey
{
private Doohickey _doohicky;
public ReadOnlyDoohickey(Doohickey doohicky)
{
this._doohicky = doohicky;
}
public string ItemName
{
get { return _doohicky.ItemName; }
}
public void DoSomthing()
{
this._doohicky.DoSomthing();
}
}
Is it OK to create another object when you need a readonly copy? If so then you can use the technique in the included code. If not, I think a wrapper is probably your best bet when it comes to this.
internal class Test
{
private int _id;
public virtual int ID
{
get
{
return _id;
}
set
{
if (ReadOnly)
{
throw new InvalidOperationException("Cannot set properties on a readonly instance.");
}
}
}
private string _name;
public virtual string Name
{
get
{
return _name;
}
set
{
if (ReadOnly)
{
throw new InvalidOperationException("Cannot set properties on a readonly instance.");
}
}
}
public bool ReadOnly { get; private set; }
public Test(int id = -1, string name = null)
: this(id, name, false)
{ }
private Test(int id, string name, bool readOnly)
{
ID = id;
Name = name;
ReadOnly = readOnly;
}
public Test AsReadOnly()
{
return new Test(ID, Name, true);
}
}
I would suggest that for each main class or interface, there be three defined classes: a "readable" class, a "changeable" class, and an "immutable" class. Only the "changeable" or "immutable" classes should exist as concrete types; they should both derive from an abstract "readable" class. Code which wants to store an object secure in the knowledge that it never changes should store the "immutable" class; code that wants to edit an object should use the "changeable" class. Code which isn't going to write to something but doesn't care if it holds the same value forever can accept objects of the "readable" base type.
The readable version should include public abstract methods AsChangeable(), AsImmutable(), public virtual method AsNewChangeable(), and protected virtual method AsNewImmutable(). The "changeable" classes should define AsChangeable() to return this, and AsImmutable to return AsNewImmutable(). The "immutable" classes should define AsChangeable() to return AsNewChangeable() and AsImmutable() to return this.
The biggest difficulty with all this is that inheritance doesn't work terribly well if one tries to use class types rather than interfaces. For example, if one would like to have an EnhancedCustomer class which inherits from BasicCustomer, then ImmutableEnhancedCustomer should inherit from both ImmutableBasicCustomer and ReadableEnhancedCustomer, but .net doesn't allow such dual inheritance. One could use an interface IImmutableEnhancedCustomer rather than a class, but some people would consider an 'immutable interace' to be a bit of a smell since there's no way a module that defines an interface in such a way that outsiders can use it without also allowing outsiders to define their own implementations.
Abandon hope all ye who enter here!!!
I suspect that in the long run your code is going to be very confusing. Your class diagram suggests that all properties are editable (or not) in a given object. Or are your (I'm)mutable interfaces introducing new properties that are all immutable or not, separate from the "core"/inheriting class?
Either way I think you're going to end up with playing games with property name variations and/or hiding inherited properties
Marker Interfaces Perhaps?
Consider making all properties in your classes mutable. Then implement IMutable (I don't like the name IItem) and IImutable as a marker interfaces. That is, there is literally nothing defined in the interface body. But it allows client code to handle the objects as a IImutable reference, for example.
This implies that either (a) your client code plays nice and respects it's mutability, or (b) all your objects are wrapped by a "controller" class that enforces the given object's mutability.
Could be too late :-), but the cause "The keyword 'new' is required on property because it hides property ..." is a bug in Resharper, no problem with the compiler. See the example below:
public interface IEntityReadOnly
{
int Prop { get; }
}
public interface IEntity : IEntityReadOnly
{
int Prop { set; }
}
public class Entity : IEntity
{
public int Prop { get; set; }
}
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
var entity = new Entity();
(entity as IEntity).Prop = 2;
Assert.AreEqual(2, (entity as IEntityReadOnly).Prop);
}
}
Same for the case without interfaces. The only limitation, you can't use auto-properties
public class User
{
public User(string userName)
{
this.userName = userName;
}
protected string userName;
public string UserName { get { return userName; } }
}
public class UserUpdatable : User
{
public UserUpdatable()
: base(null)
{
}
public string UserName { set { userName = value; } }
}
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
var user = new UserUpdatable {UserName = "George"};
Assert.AreEqual("George", (user as User).UserName);
}
}
I again need help by you, this time I struggle with covariance, contravariance, delegates and an simple idea blowing up...
I want to implement an attribute for our businessobject-properties that takes a delegate and the needed parameters for that one, so that I can work with reflection, read out the attribute and perform a validation on the property value.
The reason behind this is, we are using Windows.Forms with DataBinding and need to set the DataBinding update method to OnPropertyChanged, to get a properly working refresh on the GUI.
We do need however a way to react in the validating-events of the controls to validate the property correctly, to see if the user can actually e.g. save the object. But the Validating-Event of the control occurs only after writing the value to the property. Having a validation in the setter of the property would cause a crash and we could not provide the user exact information what is wrong unless we implement the validation a second time (or extract it to a method called from the setter).
To keep this most elegant and clean, I thought one of the following would be nice to have:
[PropertyValidator(ValidationHelper.ValidateString, new StringValidatorArgs(true, 3, 15))]
That way I could iterate via reflection over all properties, perform all validations we want them to and set a PropertyValidator-Attribute for with the correct Method. But I played with the idea a bit and do not get this anyway to work, here is what I have, might be you have an idea about how to achive this.
public delegate bool Validator(object validatee, ValidatorArgs v);
public class ValidatorArgs
{
}
public class StringValidatorArgs : ValidatorArgs
{
public StringValidatorArgs(bool nullCheck, int minLength, int maxLength)
{
this.NullCheck = nullCheck;
this.MinLength = minLength;
this.MaxLength = maxLength;
}
public bool NullCheck { get; set; }
public int MinLength { get; set; }
public int MaxLength { get; set; }
}
public class MyClass
{
[PropertyValidator(ValidationHelper.ValidateString, new StringValidatorArgs(true, 3, 15))]
public string MyString { get; set; }
}
public static class ValidationHelper
{
public static bool ValidateString(object validatee, StringValidatorArgs v)
{
return true;
}
}
[AttributeUsage(AttributeTargets.Property, Inherited = true, AllowMultiple = true)]
public class PropertyValidatorAttribute
: Attribute
{
#region Constructor
private PropertyValidatorAttribute()
{
}
public PropertyValidatorAttribute(Validator validator, ValidatorArgs args)
{
this.Validator = validator;
this.Args = args;
}
#endregion
#region Properties
public Validator Validator
{
get;
private set;
}
public ValidatorArgs Args
{
get;
private set;
}
#endregion
}
Any hints welcome...
What about implementing IDataErrorInfo to provide validation information from your object, instead of (I'm assuming) throwing an exception from the setter on bad data? Most Windows Forms controls are IDataErrorInfo savvy, and will provide corresponding UI validation information on a per-property or per-object basis.