I have a class with about 20 properties but I'd simplify it for this question:
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
}
I'd like to have a class or property that identifies whether my class is dirty. By this I mean to identify whether any of its values have changed?
There are 3 design approaches I can take:
1)
When setting the property inside the class, I check whether the property IsDirty.
public string Name
{
get { return this._name; }
set { if (this._name != value) { this.IsDirty = true; this._name = value; }
}
2)
When setting the property from outside the class, I check whether the property IsDirty.
e.g.
if (p.Name != newName)
{
p.IsDirty = true;
p.Name = newName;
}
This approach forces me to add lots of ifs in the client class. Some properties are even collections or even reference objects so the number of lines would be increased even.
3)
When the object is ready to be saved, then I check whether any properties IsDirty by getting a cloned object and checking the equality.
This would have a poorer performance as I would have to clone or load again the original object then compare the properties one by one.
Which one is the best design? or is there any other design pattern that can help with this?
Another option would be to Implement the INotifyPropertyChanged Interface.
Please note that this will help you make thing more tidy and your API clearer, but as far as internal implementation regarding keeping track after changes, It is still up to you to implement. I think this goes along best with your Option #1
Option 1 is clearly best: it puts the responsibility of tracking dirtiness where it belongs: inside the object. Option 2 is out because as you mentioned, you are forcing this responsibility onto the clients of your classes. And option 3 has the additional problem as you mentioned of performance.
Incidentally, you should look into a proxy implementation using DynamicProxy. This will allow your code to look like this:
public class Product
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
}
and with the judicious use of interceptors, you can get the behaviour you want. You can write an interceptor to intercept any "sets" and do some logic inside, such as setting an IsDirty flag.
Another idea would be to make this a GoF Observable and let interested Observer parties register their interest in changes. It's a more event-based approach.
This is the best solution and complies with SRP principle very nicely, I created the below classes:
ProductWithChangeDetection; this uses the Decorator pattern to add this new feature to an existing product object
ProductChangeDetector; this contains logics for checking and notification. Currently only exposes ChangeDetected property but if more complexity needed one should implement INotifyPropertyChange interface.
ProductEquitable; this implements IEquitable and has some overloads for checking whether two objects/properties are equal
Related
I'm writing a permissions service for my app, and part of this service's responsibility is to check that a user has permission to access the particular object they are trying to change. There are around 6 six different objects that can be mutated, and they all possess a particular property called tenant. This tenant prop is what I need to check.
The issue is that I want to keep my code as DRY as possible, but I can't see anyway of not repeating myself in this particular situation. I have six different objects which I need to check, therefore I have six different IDs and six different calls to the database to retrieve the information I need.
I'm reluctant to write six different methods each supporting the different objects I need to check, but since the code is going to look something like the below (vastly simplified) I'm not sure if there's anything I can do differently.
public bool CheckUserHasPermissionForObject(string id)
{
var obj = _dataRepository.GetObjById(id);
var userHasPermission = UserHasPermission(obj);
return userHasPermission;
}
I was hoping delegate types would lend a hand here but I don't think they'll help either.
There are few options there.
Option 1: Using interfaces
You can create an interface class that has the property tenant:
// TODO: Rename this class
public interface IParentClass
{
string Tenant { get; set; }
}
Then derive all your six objects from that:
// TODO: Rename this class
public class ChildClass1 : IParentClass
{
public string Tenant { get; set; }
}
// TODO: Rename this class
public class ChildClass2 : IParentClass
{
public string Tenant { get; set; }
}
//... TODO: Derive the others as well
And then modify your method to check that property like this:
public bool CheckUserHasPermissionForObject(string id)
{
var obj = _dataRepository.GetObjById(id) as IParentClass;
var userHasPermission = UserHasPermission(obj);
return userHasPermission;
}
private bool UserHasPermission(IParentClass obj)
{
// TODO: Implement your check here
if (obj.Tenant == "Whatever")
{
// TODO: Implement your logic here
}
return false;
}
Option 2: Using reflections
You can get the value of the property called "tenant" of different objects with reflections like this:
var tenantValue = obj.GetType().GetProperty("tenant").GetValue(obj, null);
This will try to find a property called "tenant" in any object, and return the value.
P.S. Option 3 might be using some generics, but not sure, as the question is not that clear at this moment.
The issue is that I want to keep my code as DRY as possible, but I can't see anyway of not repeating myself in this particular situation. I have six different objects which I need to check, therefore I have six different IDs and six different calls to the database to retrieve the information I need.
If the logic for checking permissions is not the same, then by definition you aren't repeating yourself. Don't make your code arcane or unreadable all in the name of DRY.
Because you're making 6 distinct calls to the database, your options for reusing code are limited.
I'm reluctant to write six different methods each supporting the different objects I need to check.
If the objects have different ways to verify the permissions, there is no way around this. Either the objects are all the same (and can inherit some sort of shared logic), or they aren't. Objects that look similar but aren't actually the same should be kept separate.
My recommendation
In order to communicate similar functionality (but different implementation), I'd use an interface. Maybe something like
public interface IUserPermission
{
string Tenant { get; set; }
bool CheckUserHasPermissions(string id);
}
This interface makes the calling code more consistent and better communicates how the objects are meant to interact. Notably, this does not reduce the amount of code written. It just documents/explains the intention of the code.
Alternative solution
Ultimately, the code will need to be able to distinguish your different types of objects. But technically you could write one giant function that switches based on object type instead of splitting the logic across the six different objects. I personally find this organization hard to read and debug, but you could technically write some sort of utility (extension) method like this:
public static bool CheckUserHasPermissions(this object obj, string id)
{
if (obj is Type1)
return CallDatabase1(id);
if (obj is Type2)
return CallDatabase2(id);
throw new ArgumentException("Unsupported object type.", nameof(obj));
}
In DDD it is customary to protect an entity's properties like this:
public class Customer
{
private Customer() { }
public Customer(int id, string name) { /* ...populate properties... */ }
public int Id { get; private set; }
public string Name { get; private set; }
// and so on...
}
EF uses reflection so it can handle all those privates.
But what if you need to attach an entity without loading it (a very common thing to do):
var customer = new Customer { Id = getIdFromSomewhere() }; // can't do this!
myContext.Set<Customer>().Attach(customer);
This won't work because the Id setter is private.
What is a good way to deal with this mismatch between the language and DDD?
Ideas:
make Id public (and break DDD)
create a constructor/method to populate a dummy object (makes no sense)
use reflection ("cheat")
???
I think the best compromise, is to use reflection, and set that private Id property, just like EF does. Yes it's reflection and slow, but much faster than loading from the database. And yes it's cheating, but at least as far as the domain is concerned, there is officially no way to instantiate that entity without going through the constructor.
How do you handle this scenario?
PS I did a simple benchmark and it takes about 10s to create a million instances using reflection. So compared to hitting the database, or the reflection performed by EF, the extra overhead is tiny.
"customary" implicitly means it's not a hard set rule, so if you have specific reasons to break those rules in your application, go for it. Making the property setter public would be better than going into reflection for this: not only because of performance issues, but also because it makes it much easier to put unwanted side-effects in your application. Reflection just isn't the way to deal with this.
But I think the first question here is why you would want the ID of an object to be set from the outside in the first place. EF uses the ID primarily to identify objects and you should not use the ID for other logic in your application than just that.
Assuming you have a strong reason to want to change the ID, I actually think you gave the answer yourself in the source you just put in the comments:
So you would have methods to control what happens to your objects and
in doing so, constrain the properties so that they are not exposed to
be set or modified “willy nilly”.
You can keep the private setter and use a method to set the ID.
EDIT:
After reading this I tried doing some more testing myself and you could have the following:
public class Customer
{
private Customer() { }
public Customer(int id) { /* only sets id */ }
public Customer(int id, string name) { /* ...populate properties... */ }
public int Id { get; private set; }
public string Name { get; private set; }
// and so on...
public void SetName(string name)
{
//set name, perhaps check for condition first
}
}
public class MyController
{
//...
var customer = new Customer(getIdFromSomewhere());
myContext.Set<Customer>().Attach(customer);
order.setCustomer(customer);
myContext.SaveChanges(); //sets the customer to order and saves it, without actually changing customer: still read as unchanged.
//...
}
This code leaves the private setters as they were (you will need the methods for editing of course) and only the required changes are pushed to the db afterwards. As is also explained in the link above, only changes made after attaching are used and you should make sure you don't manually set the state of the object to modified, else all properties are pushed (potentially emptying your object).
This is what I'm doing, using reflection. I think it's the best bad option.
var customer = CreateInstanceFromPrivateConstructor<Customer>();
SetPrivateProperty(p=>p.ID, customer, 10);
myContext.Set<Customer>().Attach(customer);
//...and all the above was just for this:
order.setCustomer(customer);
myContext.SaveChanges();
The implementations of those two reflection methods aren't important. What is important:
EF uses reflection for lots of stuff
Database reads are much slower than these reflection calls (the benchmark I mentioned in the question shows how insignificant this perf hit is, about 10s to create a million instances)
Domain is fully DDD - you can't create an entity in a weird state, or create one without going through the constructor (I did that above but I cheated for a specific case, just like EF does)
I am using Entity Framework and Code First approach in a WPF MVVM application backed by a SQL CE database. I am trying to design a model class that can simply update one of its property values in response to another one of its property values changing. Basically, I am looking for a way to define a poco that is "self-tracking" after the instance is initialized by EF. If the answer involves abandoning Code First, then maybe that is the only viable route (not sure). A basic example:
class ThingModel
{
public int Id { get; set; }
public bool OutsideDbNeedsUpdate { get; set; }
private string _foo;
public string Foo
{
get { return _foo; }
set
{
if (_foo != value)
{
_foo = value;
OutsideDbNeedsUpdate = true;
}
}
}
}
However, the problem with the above is that whenever DbContext is initializing an instance at runtime and setting the fields, my class is prematurely setting the dependent field in response. In other words, I am searching for a simple pattern that would allow my poco class to ONLY do this special change tracking after EF has finished initializing the fields on an instance.
I realize I could do something like the solution here
but my business case requires that this special change tracking be decoupled from the EF change tracking, in other words, I require the ability to SaveChanges regardless of the state of the HasChanges property above. This is because I would like to be able to periodically check the HasChanges property on my entities and in turn update dependent values in an outside database (not the same one backing the EF DbContext) and many changes/saves may happen to the EF DB between pushes to the outside DB. Hence the reason I was hoping to just persist the flag with the record in my DB and reset it to false when the periodic update to the outside DB occurs.
After your edit I think you can use the ObjectMaterialized event.
This event is raised after all scalar, complex, and reference properties have been set on an object, but before collections are loaded.
Put this in the constructor of your DbContext:
((IObjectContextAdapter)this).ObjectContext.ObjectMaterialized +=
HandleObjectMaterialized;
And the method:
private void HandleObjectMaterialized(object sender, ObjectMaterializedEventArgs e)
{ }
Now the question is, what to put in the method body? Probably the easiest solution is to define an interface
interface IChangeTracker
{
bool Materialized { get; set; }
bool OutsideDbNeedsUpdate { get; }
}
and let the classes you want to track implement this interface.
Then, in HandleObjectMaterialized you can do:
var entity = e.Entity as IChangeTracker;
if (entity != null)
{
entity.Materialized = true;
}
After this you know when you can set OutsideDbNeedsUpdate internally.
Original text
Generally it is not recommended to have properties with side effects (well, more exact, with more side effects than changing the state the represent). Maybe there are exceptions to this rule, but most of the time it is just not a good idea to have dependencies between properties.
I have to guess a bit what you can do best, because I don't know what your real code is about, but it might be possible to put the logic in the getter. Just an example:
public State State
{
get { return this.EndDate.HasValue ? MyState.Completed : this._state; }
set { this._state = value; }
}
This does not remove the mutual dependencies, but it defers the moment of effect to the time the property is accessed. Which in your case may be not sooner than SaveChanges().
Another strategy is making a method that sets both properties at once. Methods are expected to have side effects, especially when their names clearly indicate it. You could have a method like SetMasterAndDependent (string master).
Now methods are not convenient in data binding scenarios. In that case you better let the view model set both properties or call the method as above.
I have two tables in the database that are used almost for the same thing, but the tables don't have exactly the same structure.
Lets say I have one table for manual requests and another table for automatic requests. I have to load both tables into the same GridView and I'm using custom business objects.
To illustrate the question I'll call TManualReqTable and TAutomaticReqTable.
TManualReqTable
- ID
- Field1
- Field2
- Field3
- Field4
and
TAutomaticReqTable
- ID
- Field1
- Field3
In the code, I'm using the same object for these two tables. I have an interface with all the properties of both tables and I'm checking if the field exists when I'm loading the data to the object.
But I'm thinking this should be created with two objects and one superclass with abstracts methods.
What is your opinion about it?
I would create an interface IRequest that describes the fields & methods common to both, and then interfaces & classes for ManualRequest and AutomaticRequest that implement IRequest and also add the methods/fields unique to each of them.
You can use IRequest as the type for something that incorporates either one. When iterating through something that can include data from either, you can check whether each object implements the interfaces:
foreach (IRequest obj in RequestList) {
// do stuff that uses the common interface
if (obj is IManualRequest) {
// do stuff specific to manual requests
} else if (obj is IAutomaticRequest) {
// likewise
}
}
I follow a general rule to avoid creating base classes unless:
I've already designed or discovered sufficient commonality to give sufficient substance to the base class.
I have a use case for consuming the classes as the base class; if I don't have anything that can operate on the common functionality of the classes, there's little value in having a base class (can achieve the same functionality through composition of a class implementing the common behaviors.)
The requirements are sufficiently stable that I believe the base class abstraction will hold without significant modification in the future. Base classes become increasingly difficult to modify over time.
IMO, forget how the database looks like for a minute or two.
Think of how it should be structured as an object.
Think of how you would like to use that object. If you need to visualize, write some code of that yet non-existing object and tweak it until it looks elegant.
Think of how to make it happen.
model first development
Hope it helps.
well, there are a few assumptions i'm making here, so let me make them explicit...
given:
this is primarily a difference in query/display logic
the display logic can already handle the nulls
the underlying object being represented is the same between the two items
there's a simple way of determining whether this was a 'manual' or an 'automatic' call
i would say that inheritance is not the way i would model it. why? because it's the same object, not two different kinds of object. you're basically just not displaying a couple of the fields, and therefore do not need to query them.
so, i would probably try to accomplish something that makes clear the nature of the difference between the two (keep in mind that i intend this to show a way of organizing it so that it's clear, any particular implementation might have different needs; the main idea to glean is treating the differences as what they are: differences in what gets queried based upon some sort of condition.
public enum EQueryMode
{
Manual,
Automatic
}
public class FieldSpecification
{
public string FieldName { get; set; }
public bool[] QueryInMode { get; set; }
public FieldSpecification
(
string parFieldName,
bool parQueryInManual,
bool parQueryInAutomatic
)
{
FieldName = parFieldName;
QueryInMode = new bool[] { parQueryInManual, parQueryInAutomatic };
}
}
public class SomeKindOfRecord
{
public List<FieldSpecification> FieldInfo =
new List<FieldSpecification>()
{
new FieldSpecification("Field1", true, true),
new FieldSpecification("Field2", true, false),
new FieldSpecification("Field3", true, true),
new FieldSpecification("Field4", true, false)
};
// ...
public void PerformQuery(EQueryMode QueryMode)
{
List<string> FieldsToSelect =
(
from f
in FieldInfo
where
f.QueryInMode[(int)QueryMode]
select
f.FieldName
)
.ToList();
Fetch(FieldsToSelect);
}
private void Fetch(List<string> Fields)
{
// SQL (or whatever) here
}
}
edit: wow i can't seem to make a post today without having to correct my grammar! ;)
I've created some classes that will be used to provide data to stored procedures in my database. The varchar parameters in the stored procs have length specifications (e.g. varchar(6) and I'd like to validate the length of all string properties before passing them on to the stored procedures.
Is there a simple, declarative way to do this?
I have two conceptual ideas so far:
Attributes
public class MyDataClass
{
[MaxStringLength = 50]
public string CompanyName { get; set; }
}
I'm not sure what assemblies/namespaces I would need to use to implement this kind of declarative markup. I think this already exists, but I'm not sure where and if it's the best way to go.
Validation in Properties
public class MyDataClass
{
private string _CompanyName;
public string CompanyName
{
get {return _CompanyName;}
set
{
if (value.Length > 50)
throw new InvalidOperationException();
_CompanyName = value;
}
}
}
This seems like a lot of work and will really make my currently-simple classes look pretty ugly, but I suppose it will get the job done. It will also take a lot of copying and pasting to get this right.
I'll post this as a different answer, because it is characteristically different than Code Contracts.
One approach you can use to have declarative validation is to use a dictionary or hash table as the property store, and share a utility method to perform validation.
For example:
// Example attribute class for MaxStringLength
public class MaxStringLengthAttribute : Attribute
{
public int MaxLength { get; set; }
public MaxStringLengthAttribute(int length) { this.MaxLength = length; }
}
// Class using the dictionary store and shared validation routine.
public class MyDataClass
{
private Hashtable properties = new Hashtable();
public string CompanyName
{
get { return GetValue<string>("CompanyName"); }
[MaxStringLength(50)]
set { SetValue<string>("CompanyName", value); }
}
public TResult GetValue<TResult>(string key)
{
return (TResult)(properties[key] ?? default(TResult));
}
public void SetValue<TValue>(string key, TValue value)
{
// Example retrieving attribute:
var attributes = new StackTrace()
.GetFrame(1)
.GetMethod()
.GetCustomAttributes(typeof(MaxStringLengthAttribute), true);
// With the attribute in hand, perform validation here...
properties[key] = value;
}
}
You can get at the calling property using reflection by working up your stack trace as demonstrated here. Reflect the property attributes, run your validation, and voila! One-liner getter/setters that share a common validation routine.
On an aside, this pattern is also convenient because you can design a class to use alternative dictionary-like property stores, such as ViewState or Session (in ASP.NET), by updating only GetValue and SetValue.
One additional note is, should you use this approach, you might consider refactoring validation logic into a validation utility class for shared use among all your types. That should help prevent your data class from getting too bulky in the SetValue method.
Well, whatever way you go, what's executed is going to look like your second method. So the trick is getting your first method to act your second.
First of all, It would need to be [MaxStringLength(50)]. Next, all that's doing is adding some data to the Type object for this class. You still need a way of putting that data to use.
One way would be a binary re-writer. After compilation (but before execution), the rewriter would read the assembly, looking for that Attribute, and when finding it, add in the code for the check. The retail product PostSharp was designed to do exactly that type of thing.
Alternately, you could trigger it at run-time. SOmething like:
public class MyDataClass
{
private string _CompanyName;
[MaxStringLength(50)]
public string CompanyName
{
get {return _CompanyName;}
set
{
ProcessValidation()
_CompanyName = value;
}
}
}
That's still quite ugly, but it's a bit better if you have a number of validation attributes.
The first method using attribute sounds good.
Implement your attribute by inherit from the System.Attribute class and mark your class with AttributeUsage attribute to let your attribute being set on a field.
Then, using reflection, check for presence and value of the attribute before sending the value to the SP.
Thats provide you with lot more flexibility than the second method. If tomorow you decide to let your SP receive the first N chars of a too lengthly string, you won't have to modify all your code but only the one that interpret the attribute.
There are indeed some validation attribute in the framework but I wouldn't use those one because you could implies some behaviour you don't expect and because you won't be able to modify then in any way (liek if you want something like [MaxLength(50, true)] to specify that using the first 5O chars is OK.
It sounds like a business rule. So I would put it in a Company class (Since it is CompanyName), and do the validation there. I don't see why it would require copying and pasting if you have it encapsulated.
Either an attribute or your second example should be fine. The attribute allows for reuse in other classes with string length constraints, however.
Though not exactly the same thing, I recently became aware of .NET 4 Code Contracts in an MSDN article. They provide a convenient and elegant way of encoding and analyzing code assumptions. It's worth taking a look at.