Injecting properties into .NET classes post-compile - c#

I'd like to implement the ViewModel part of WPF's MVVM pattern without referencing WPF assemblies. The problematic part is command routing, which requires that ViewModels implement properties of type ICommand so that command bindings can work.
Now, I can avoid the ICommand and simply declare the properties as object. Everything still works, so that's that. But what bothers me is, I still have to declare them, and I really don't want to, because they feel like boiler plate code.
My ViewModels currently look like this:
public class HelloWorldViewModel : ViewModel
{
[BoundProperty]
public string Name { get; set; }
[CommandHandler("SayHello")]
public bool CanSayHello()
{
return Name != "" && Name != null;
}
[CommandHandler("SayHello")]
public void SayHello()
{
View.ShowMessage("Hello, {0}!", Name);
}
public object SayHello { get; private set; }
}
The CommandHandlerAttribute enables runtime discovery of command handlers (an Action and an optional Func<bool>), while the BoundPropertyAttribute is really an aspect that injects itself into the property setter and calls INotifyPropertyChanged. I accompish this by using a compile time IL weaver.
Ideally, I'd like to make the last line (the SayHello property) implicit, too. There would be no point in having it there in the source if it wasn't for WPF's requirement.
So, naturally, I'm thinking of using the CommandHandlerAttribute aspect to inject the necessary IL into class and essentially creating the property post-compile. This is quite hard, although a good IL weaver (such as PostSharp) can go a long way to make it easier.
Before I embark on this journey, I'd like to hear what you all think of my approach. Is it sound? Is there a better way? How would/do you do it?

To me this sounds too clever by far. There's too much "magic" happening. In particular, I dislike the magic strings and other aspects of your CommandHandlerAttribute. That said, if I were to go down this route, I'd use something akin to the EventAggregator but for commands. IOW, SayHello wouldn't exist on your ViewModel at all. What ever magic creates the command bindings to SayHell() and CanSayHello() would instead locate the command in the global CommandAggregator. As long as we're using magic strings for this, the commands in the CommandAggregator could be lazily created, thus requiring no "boiler plate" coding on your part. All that's left is to create some XAML magic (markup extension) to specify the command on the ICommandSource.
<Button Command="{my:AggregateCommand SayHello}"/>

i advice you to see how this was implemented, and it will help:
"Kind Of Magic"
Effortless INotifyPropertyChanged
[http://visualstudiogallery.msdn.microsoft.com/d5cd6aa1-57a5-4aaa-a2be-969c6db7f88a][1]
as an example for adding it to one property:
[Magic]
public string Name { get { return _name; } set { _name = value; } }
string _name;
Another example for adding it to all the class properties:
[Magic]
public class MyViewModel: INotifyPropertyChanged
{
public string Name { get; set; }
public string LastName { get; set; }
.....
}

Some time after playing with Prism, but before I'd seem the MVVM stuff, I came up with a strategy that I still think has some validity:
I created an implementation of the ICommand interface based on reflection. The constructor accepted a target object and an operation name. Using reflection, the code looked for a method with name "[operation]", property or method with name "Can[operation]" or "[operation]Enabled" and an event with name "Can[operation]Changed" or "[operation]Enabled Changed". Only the first was required, but the reflected method/property/event were wired up to a pretty basic implementation of the ICommand interface.
I then created an implementation of IValueConverter that would create an instance of the previous class, passing the value to be converted as the target object, and the parameter of the converter being the operation name.
Given the above components, I was then able to, for example, bind a button's Command property directly to the source of the operation (along with specifying the converter), and set the Button's CommandParameter property to the name of the operation. In this way, I got declarative command binding without the command source having carnal knowledge of anything WPF.

My personal opinion is that this is interesting, but I would avoid it in general.
Avoiding boiler-plate code (or code that feels like boiler plate code) has consequences. It may seem like a good idea, since you're not retyping things constantly, but in the long run, you're making it less readable and understandable.
Personally, I try to just setup good code templates to insert the boiler plate code for me, and wrap it in regions so I can hide it in the source code. The 30 seconds it takes to fill in a file with boiler plate in that case is less painful (for me) than the 2 hours I spend, two years later when I'm trying to understand the code, or worse, the two weeks somebody else spends two years later when they're trying to understand my code....

The best way in your case is Proxy or Decorator pattern I think. You can low level entities that are wrapped/decorated with UI/WPF stuff members during runtime. This is the simplest but yet efficient way to save your time and don't bother with frameworks, injections, etc.
The only thing is you will have to design some small infrastructure to wrap your entities with appropriate decorators.

Related

Scope of class variables in C# [duplicate]

First off, I have read through a list of postings on this topic and I don't feel I have grasped properties because of what I had come to understand about encapsulation and field modifiers (private, public..ect).
One of the main aspects of C# that I have come to learn is the importance of data protection within your code by the use of encapsulation. I 'thought' I understood that to be because of the ability of the use of the modifiers (private, public, internal, protected). However, after learning about properties I am sort of torn in understanding not only properties uses, but the overall importance/ability of data protection (what I understood as encapsulation) within C#.
To be more specific, everything I have read when I got to properties in C# is that you should try to use them in place of fields when you can because of:
1) they allow you to change the data type when you can't when directly accessing the field directly.
2) they add a level of protection to data access
However, from what I 'thought' I had come to know about the use of field modifiers did #2, it seemed to me that properties just generated additional code unless you had some reason to change the type (#1) - because you are (more or less) creating hidden methods to access fields as opposed to directly.
Then there is the whole modifiers being able to be added to Properties which further complicates my understanding for the need of properties to access data.
I have read a number of chapters from different writers on "properties" and none have really explained a good understanding of properties vs. fields vs. encapsulation (and good programming methods).
Can someone explain:
1) why I would want to use properties instead of fields (especially when it appears I am just adding additional code
2) any tips on recognizing the use of properties and not seeing them as simply methods (with the exception of the get;set being apparent) when tracing other peoples code?
3) Any general rules of thumb when it comes to good programming methods in relation to when to use what?
Thanks and sorry for the long post - I didn't want to just ask a question that has been asked 100x without explaining why I am asking it again.
1) why I would want to use properties
instead of fields (especially when it
appears I am just adding additional
code
You should always use properties where possible. They abstract direct access to the field (which is created for you if you don't create one). Even if the property does nothing other than setting a value, it can protect you later on. Changing a field to a property later is a breaking change, so if you have a public field and want to change it to a public property, you have to recompile all code which originally accessed that field.
2) any tips on recognizing the use of
properties and not seeing them as
simply methods (with the exception of
the get;set being apparent) when
tracing other peoples code?
I'm not totally certain what you are asking, but when tracing over someone else's code, you should always assume that the property is doing something other than just getting and setting a value. Although it's accepted practice to not put large amounts of code in getters and setter, you can't just assume that since it's a property it will behave quickly.
3) Any general rules of thumb when it
comes to good programming methods in
relation to when to use what?
I always use properties to get and set methods where possible. That way I can add code later if I need to check that the value is within certain bounds, not null etc. Without using properties, I have to go back and put those checks in every place I directly accessed the field.
One of the nice things about Properties is that the getter and the setter can have different levels of access. Consider this:
public class MyClass {
public string MyString { get; private set; }
//...other code
}
This property can only be changed from within, say in a constructor. Have a read up on Dependency Injection. Constructor injection and Property injection both deal with setting properties from some form of external configuration. There are many frameworks out there. If you delve into some of these you will get a good feel for properties and their use. Dependency injection will also help you with your 3rd question about good practice.
When looking at other people's code, you can tell whether something is a method or a property because their icons are different. Also, in Intellisence, the first part of a property's summary is the word Property.
You should not worry about the extra code needed for accessing fields via properties, it will be "optimized" away by the JIT compiler (by inlining the code). Except when it is too large to be inlined, but then you needed the extra code anyway.
And the extra code for defining simple properties is also minimal:
public int MyProp { get; set; } // use auto generated field.
When you need to customize you can alway define your own field later.
So you are left with the extra layer of encapsulation / data protection, and that is a good thing.
My rule: expose fields always through properties
While I absolutely dislike directly exposing fields to the public, there's another thing: Fields can't be exposed through Interfaces; Properties can.
There are several reasons why you might want to use Properties over Fields, here are just a couple:
a. By having the following
public string MyProperty { get; private set; }
you are making the property "read only". No one using your code can modify it's value. There are cases where this isn't strictly true (if your property is a list), but these are known and have solutions.
b. If you decide you need to increase the safety of your code use properties:
public string MyProperty
{
get { return _myField; }
set
{
if (!string.IsNullOrEmpty(value))
{
_myField = value;
}
}
}
You can tell they're properties because they don't have (). The compiler will tell you if you try to add brackets.
It's considered good practise to always use properties.
There are many scenarios where using a simple field would not cause damage, but
a Property can be changed more easily later, i.e. if you want to add an event whenever the value changes or want to perform some value/range checking.
Also, If you have several projects that depend on each other you have to recompile all that depend on the one where a field was changed to a property.
Using fields is usually practiced in private classes that is not intended to share data with other classes, When we want our data to be accessible by other classes we use properties which has the ability to share data with other classes through get and set which are access methods called Auto Properties that have access to data in private classes, also you can use both with access modifiers Full Property in the same class allowing the class to use data privately as data field and in the same time link the private field to a property that makes the data accessible to other classes as well, see this simple example:
private string _name;
public string Name
{
get
{
return _name;
}
set
{
_name = value;
}
}
The private string _name is used by the class only, while the Name property is accessible by other classes in the same namespace.
why I would want to use properties instead of fields (especially when it appears I am just adding additional code
You want to use properties over fields becuase, when you use properties you can use events with them, so in a case when you want to do some action when a property changes, you can bind some handlers to PropertyChanging or PropertyChanged events. In case of fields this is not possible. Fields can either be public or private or protected, in case of props you can make them read-only publicly but writable privately.
any tips on recognizing the use of properties and not seeing them as simply methods (with the exception of the get;set being apparent) when tracing other peoples code?
A method should be used when the return value is expected to be dynamic every-time you call, a property should be used when the return value is not that greatly dynamic.
Any general rules of thumb when it comes to good programming methods in relation to when to use what?
Yes, I strongly recommend to read Framework Design guidelines for best practices of good programming.
Properties are the preferred way to cover fields to enforce encapsulation. However, they are functional in that you can expose a property that is of a different type and marshal the casting; you can change access modifiers; they are used in WinForms data binding; they allow you to embed lightweight per-property logic such as change notifications; etc.
When looking at other peoples code, properties have different intellisense icons to methods.
If you think properties are just extra code, I would argue sticking with them anyway but make your life easier by auto-generating the property from the field (right-click -> Refactor -> Encapsulate Field...)
Properties allow you to do things other than set or get a value when you use them. Most notably, they allow you to do validation logic.
A Best Practice is to make anything exposed to the public a Property. That way, if you change the set/get logic at a later time, you only have to recompile your class, not every class linked against it.
One caveat is that things like "Threading.Interlocked.Increment" can work with fields, but cannot work with properties. If two threads simultaneously call Threading.Interlocked.Increment on SomeObject.LongIntegerField, the value will get increased by two even if there is no other locking. By contrast, if two threads simultaneously call Threading.Interlocked.Increment on SomeObject.LongIntegerProperty, the value of that property might get incremented by two, or by one, or by -4,294,967,295, or who knows what other values (the property could be written to use locking prevent values other than one or two in that scenario, but it could not be written to ensure the correct increment by two).
I was going to say Properties (setters) are a great place to raise events like NotifyPropertyChanged, but someone else beat me to it.
Another good reason to consider Properties: let's say you use a factory to construct some object that has a default constructor, and you prepare the object via its Properties.
new foo(){Prop1 = "bar", Prop2 = 33, ...};
But if outside users new up your object, maybe there are some properties that you want them to see as read-only and not be able to set (only the factory should be able to set them)? You can make the setters internal - this only works, of course, if the object's class is in the same assembly as the factory.
There are other ways to achieve this goal but using Properties and varying accessor visibility is a good one to consider if you're doing interface-based development, or if you expose libraries to others, etc.

Schrodinger's Object: WPF property won't bind/update unless I check its value code-side?

I have a Node object with a Parent that i have bound in my xaml like so,
<Label>
<Hyperlink>
<TextBlock Text="{Binding Path=Node.Parent.Name}"/>
</Hyperlink>
</Label>
My ViewModel looks something like this
public class NodeViewModel
{
public Node Node { get; set; }
public NodeViewModel(Node model)
{
Node = model;
if(model.Parent != null) { } // Check if it's null, then do nothing.
// When the above line is commented out, my label displays nothing.
}
}
Why is it that when my if statement is commented out, the label/textblock is blank? Am I doing something wrong? Does my object both exist and not exist until I check if it's null?
Edit:
Forgot to mention, my node class is pretty simple, and does implement INotifyPropertyChanged for the Name property.
2nd Edit: Added my simple Node class.
[ImplementPropertyChanged] // From Fody.PropertyChanged
public class Node
{
public int? ParentID { get; set; }
public Node Parent { get; set; }
public string Name { get; set; }
public Node Node(Node p = null)
{
Parent = p;
}
}
From comments:
It is actually. It is proxied by Entity Framework. Could that be the issue? If so, is there a less hackish way to fix this?
If the problem really lies in the proxy, then, well, no. You'll get a hard time with proxies/wrappers and WPF and change-notifications, really.
WPF's Binding engine does not work with proxies. At all. Well, maybe unless they are really well written and complex. So, usually, never. This comes form the fact how INPC interface works:
void PropertyChanged(object sender, .... args)
WPF tracks the sender and Binding.Source. If a Source of a Binding is an object called "Z", that is a Proxy to an object "A", then any notifications originating from "A" that are forwarded by proxy "Z" to the WPF's engine are .. discarded because for WPF the "Z" is the Source and it does not match the advertised sender "A".
I battled with this issue for quite a long time, and the only solution I found is to have the Proxy translate the P-Changed event so that the sender=A is subsituted for Z. This can have some nasty memory leaks when not written properly. It's because it's hard to "map" a delegate to a new delegate and provide proper disposal and GCing of both of them. And usually even this is only possible if you build your own proxies with ie. Castle or similar library. I have not found any dynamic-proxy library that supports sender-replacement out of the box.
If you know any - pleease let me know!
Anyways, be careful with the terminology. I mean, proxies. An object "Z" that wraps and trims or extends operations on another different original object "A". Your case may be different. If your so-called "proxy" is a dynamic subclass of your type and if it overrides any virtual methods/properties/events you have in your original class, then it is not the Proxy I meant. In this case, the 'proxy' and the original object is the same object, it's just that you see it as a class A and the actual class is Z:A, and for WPF the Source matches the sender. If I remember correctly, this is how EF often works.
Therefore, the first thing I'd check is to inspect who is really the culprit. Maybe Fody not EF? Try to remove that magic ImplementPropertyChanged, try to implement INPC manually in ALL classes. And I mean ALL. Both in Node and in NodeViewModel. If you are lazy, you can propdp and use DependencyProperty instead. If it works - then start removing the manual INPC and replacing it with ie. that from Fody's. When things start to break, gather all results and reanalyze.
Also, check what Fody does - maybe it provides a transparent proxy/wrapper in some point?
EDIT: Considering that your code starts working when you 'touch' the Fody'ied object, I'd start blaming Fody. Maybe it is because the NodeViewModel.Node property is currently not tracked bu Fody? Have you tried marking it with ImplementPropertyChanged too? It is a pure guess and it'd mean that this library has some serious problems, but it's quick and worth trying.
I think you are missing to implement INPC on the ViewModel. The binding won't update back to the UI when you did Node = node. Raise a property changed event on the Node setter.

How to, using dependency injection, get configuration from multiple sources?

I'm using Simple Injector, but maybe what I need is more of a conceptual answer.
Here's the deal, suppose I have an interface with my application settings:
public interface IApplicationSettings
{
bool EnableLogging { get; }
bool CopyLocal { get; }
string ServerName { get; }
}
Then, one would usually have a class which implements IApplicationSettings, getting each field from a specified source, for instance:
public class AppConfigSettings : IApplicationSettings
{
private bool? enableLogging;
public bool EnableLogging
{
get
{
if (enableLogging == null)
{
enableLogging = Convert.ToBoolean(ConfigurationManager.AppSettings["EnableLogging"];
}
return enableLogging;
}
}
...
}
HOWEVER! Let's say I want to get EnableLogging from app.config, CopyLocal from database, and ServerName from another implementation which gets the current computer name. I want to be able to mix-match my app configuration without having to create 9 implementations, one for each combination.
I'm assuming that I can't pass any parameters because the interfaces are resolved by the injector (container).
I thought of this, initially:
public interface IApplicationSettings<TEnableLogging,TCopyLocal,TServerName>
where TEnableLogging : IGetValue<bool>
where TCopyLocal : IGetValue<bool>
where TServerName : IGetValue<string>
{
TEnableLogging EnableLog{get;}
TCopyLocal CopyLocal{get;}
TServerName ServerName{get;}
}
public class ApplicationSettings<TEnableLogging,TCopyLocal,TServerName>
{
private bool? enableLogging;
public bool EnableLogging
{
get
{
if (enableLogging == null)
{
enableLogging = Container.GetInstance<TEnableLogging>().Value
}
return enableLogging;
}
}
}
However, with this I have one main problem: How do I know how to create an instance of TEnableLogging (which is a IGetValue<bool>)? Oh, assume that IGetValue<bool> is an interface which has a Value property, which will be implemented by the concrete class. But the concrete class may need some specifics (like what's the name of the key in app.config) or not (I may simply want to return always true).
I'm relatively new to dependency injection, so maybe I'm thinking in a wrong way. Does anyone have any ideas on how to accomplish this?
(You may answer using another DI library, I won't mind. I think I just need to grab the concept of it.)
You are definitely heading the wrong way here.
Some years ago I built an application that contained an interface much like your IApplicationSettings. I believe I named it IApplicationConfiguration, but it contained all application's configuration values as well.
Although it helped me make my application testable at first, after some time the design started to get in the way. A lot of implementations depended on that interface, but it kept changing a lot and with it the implementation, and the test version.
Just like you I implemented some lazy loading, but this had a terrible down side. When one of the configuration values was missing, I only found out that it did when the value was called for the first time. This resulted in a configuration that was hard to verify.
It took me a couple of iterations of refactoring to find out what the core of the problem was. Big interfaces are a problem. My IApplicationConfiguration class was violating the Interface Segregation Principle and the result was poor maintainability.
In the end I found out that this interface was completely useless. Besides violating the ISP, those configuration values described an implementation detail and instead of making an application wide abstraction, it is much better to supply each implementation directly with the configuration value they need, and only the values they need.
When you do this, the easiest thing to do is to wrap those values into a Parameter Object (even if it is just one value), and inject those configuration values into the constructor. Here's an ecample:
var enableLogging =
Convert.ToBoolean(ConfigurationManager.AppSettings["EnableLogging"]);
container.RegisterSingleton(new LoggerSettings(loggingEnabled: enableLogging));
In this case, LoggerSettings is a configuration object specific to Logger, which requires it as constructor argument.
When doing this, the enableLogging value is read just once from the configuration file and is done so during application startup. This makes it fast and makes it fail at application startup when the value is missing.

Exposing Data as C# Properties - Good or Bad?

I am kinda not getting my head around this and was wondering if someone could please help me understand this.
So here is the problem, I have a class in which there are no required parameters. If user does not set the fields I can take the default value and carry on. Previously, I designed the same class as Joshua Bloch's Builder Pattern (Effective Java) (immutable object). I didn't had any good reason for making the class immutable except for the fact that I didn't wanted to have telescopic constructors and I didn't wanted to expose the data of the class.
But now, a fellow programmer friend is trying to convince me that it's okay to expose the data from the class using C# properties. I am not sure about this and I still feel that I should not be allowing user to muck with data.
Maybe I am completely wrong in my understanding. Could someone please clear my doubt about this, that whether it's good or bad to expose the data from the class?
If it is good then in what case it is good? Or else if someone can please point me to the article/book that clarifies this I would really appreciate it.
Thanks!
Expose the data in the class if it is needed or of interest outside the class, and do not do so if it is not. Expose it read-only if it's only needed to be read outside, and expose it as a full read/write property if it should be able to be changed. Otherwise, keep it in a private field.
immutable classes are easier to reason about especially in a multi tasking application, but they usually pay in performance (because when you need to change the value of a field you need to build the whole class again with the new value).
So, you could be ok or (depending on what you're coding) even better off with properties but as usual there's no silver bullet.
Settable properties are also the only way to code objects for some specific frameworks or libraries (e.g. ORMs like NHibernate), because you can't control how the library/framework initializes the object.
About constructors, C# 4 has optional parameters, that could help you avoid a long chain of constructors and also communicate much more clearly the fact that the parameters are optional.
However I can't think of many cases where you would end up with classes with a long list of optional parameters. If you find that you're coding classes like that too often (especially with the builder pattern, which is very elegant looking on the consumers' side of the class but complicates the code for the class itself) you may be using the wrong design. Are you sure you are not asking your classes to have too many responsibilities?
It basically depend on what's the purpose of your Class in the application context (could you give us more details?).
Anyway reckon that you could make a property safe from external changes by declaring is setter as private:
http://msdn.microsoft.com/en-us/library/bb384054.aspx
public string UserName { get; private set; }
It's "good" when the consumer of the class needs the data. You have two possibilities to offer properties.
if you only want to offer a property for information purpose, then choose a read only property like this:
public string MyInformation { get; private set; }
If you have the need to allow the consumer to change that property, then make the setter public like that:
public string MyChangeableInformation { get; set; }
But if the consumer has no need to get the information, then hide it in your class!
But now, a fellow programmer friend is trying to convince me that it's
okay to expose the data from the class using C# properties. I am not
sure about this and I still feel that I should not be allowing user to
muck with data.
As a rule of thumb, methods should represent actions whereas properties represent data. What your friend might have tried telling you is that you can expose the data of your class to outside world and still maintain full control on how other classes are accessing the data. In your case, as other have mentioned, you can use properties with private setters, such that the caller should not be able to modify the data.

c# properties with repeated code

I have a class with a bunch of properties that look like this:
public string Name
{
get { return _name; }
set { IsDirty = true; _name = value; }
}
It would be a lot easier if I could rely on C# 3.0 to generate the backing store for these, but is there any way to factor out the IsDirty=true; so that I can write my properties something like this and still get the same behaviour:
[MakesDirty]
public string Name { get; set; }
No. Not without writing considerably more (arcane?) code than the original version (You'd have to use reflection to check for the attribute on the property and what not.. did I mention it being 'slower').. This is the kind of duplication I can live with.
MS has the same need for raising events when a property is changed. INotifyPropertyChanged that is a vital interface for change notifications. Every implementation I've seen yet
does
set
{
_name = value;
NotifyPropertyChanged("Name");
}
If it was possible, I'd figure those smart guys at MS would already have something like that in place..
You could try setting up a code snippet to make it easy to create those.
If you really want to go that way, to modify what the code does using an attribute, there are some ways to do it and they all are related to AOP (Aspect oriented programming). Check out PostSharp, which is an aftercompiler that can modify your code in a after compilation step. For example you could set up one custom attribute for your properties (or aspect, how it is called in AOP) that injects code inside property setters, that marks your objects as dirty. If you want some examples of how this is achieved you can check out their tutorials.
But be careful with AOP and because you can just as easily create more problems using it that you're trying to solve if not used right.
There are more AOP frameworks out there some using post compilation and some using method interception mechanisms that are present in .Net, the later have some performance drawbacks compared to the first.
No, when you use automatic properties you don't have any control over the implementation. The best option is to use a templating tool, code snippets or create a private SetValue<T>(ref T backingField, T value) which encapsulates the setter logic.
private void SetValue<T>(ref T backingField, T value)
{
if (backingField != value)
{
backingField = value;
IsDirty = true;
}
}
public string Name
{
get
{
return _name;
}
set
{
SetValue(ref _name, value);
}
}
The other alternative might be a code generator such as codesmith to automate creating the properties. This would be especially useful if the properties you are creating are columns in a database table
I can recommend to use Enterprise Library for that purpose. Policy Application Block delivers the infrastructure to do "something" (something = you can code that on your own) whenever you enter/exit a method for example. You can control the behavior with attributes. Take that as a hint an go into detail with the documentation of enterprise library.
There's a DefaultValueAttribute that can be assigned to a property, this is mainly used by the designer tools so they can indicate when a property has been changed, but, it might be a "tidy" way of describing what the default value for a property is, and thus being able to identify if it's changed.
You'd need to use Reflection to identify property changes - which isn't actually that expensive unless you're doing lots of it!
Caveat: You wouldn't be able to tell if a property had been changed BACK from a non-default value to the default one.
I'd say that the best way of solving this is to use Aspect-Oriented Programming (AOP). Mats Helander did a write up on this on InfoQ. The article is a bit messy, but it's possible to follow.
There are a number of different products that does AOP in the .NET space, i recommend PostSharp.
If you do go with Attributes, I'm fairly certain you'll have to roll your own logic to deduce what they mean and what to do about them. Whatever is using your custom class objects will have to have a way of performing these attribute actions/checks, preferably at instantiation.
Otherwise, you're looking at using maybe events. You'd still have to add the event to every set method, but the benefit there would be you're not hard-coding what to do about dirty sets on every property and can control, in one place, what is to be done. That would, at the very least, introduce a bit more code re-use.
ContextBound object. If you create a class that extends context bound object and you create a ContextAttribute you can intercept the calls made to such a property and set the IsDirty. .NET will create a proxy to your class so all calls go over something like a remoting sink.
The problem with such an approach though is that your proxy will only be invoked when called externally. I'll give you an example.
class A
{
[Foo]
public int Property1{get; set;}
public int Property2{get {return variable;} set{ Property1 = value; variable = value; }
}
When property1 is called from another class, your proxy would be invoked. But if another class calls property2, even though the set of property2 will call into property1 no proxy will be invoked, (a proxy isn't necessary when you're in the class itself).
There is a lot of sample code out there of using ContextBoundObjects, look into it.

Categories

Resources