Zze
Zze

Reputation: 18805

C# On property change, run logic

I have a C# Entity which is auto generated via database first:

public partial class Zone
{
    public Guid LocationId {get; set;}
    ...
}

What I need to do is run a function, Process() whenever LocationId is changed. Now normally I would alter the setter and job done, however because this is auto generated via database first, any "manual changes to the file will be overwritten if the code is regenerated."

What would be the best approach here?

The current thinking is to create a new partial class to do something like this:

public partial class Zone
{
    private Guid _pendingLocationId
    public Guid PendingLocationId {
      get { return _pendingLocationId }
      set { 
        Guid updatedLocation = Process(value) ?? value;
        _pendingLocationId = updatedLocation;
        locationId = updatedLocation;
      }
    }
}

Just a note; the unfortunate reality is that there is probably zero chance of us integrating a new framework or library into the application at this stage.


In response to the possible duplicate flag; Unless I have misread, this would require us re-mapping /encapsulating all of our Zone references into a new class, not only pushing this out to all the views, but also editing many linq queries etc. If someone can identify why this would be the preferred solution over my own suggested solve, then please let me know.

Upvotes: 3

Views: 268

Answers (3)

NitinSingh
NitinSingh

Reputation: 2068

Have a business entity mapped to yr database entity (via AutoMapper) and then in your business entity, incorporate the INotifyPropertyChanged interface.

Pseudo code below. This will de-couple your database from business entity and allow independent changes.

namespace DBEntity {
    public class Customer {
         public int Id { get; set; }  ...
    }
}

namespace BizEntity {
    public class Customer : INotifyPropertyChanged {
         private int id;
         public int Id { 
                  get { return this.id } ; 
                  set { 
                       this.id = value; 
                       PropertyChanged(Id...);
                       }
                  }
         NotifyPropertyChanged() {
                    ....
         }

var dbCustomer = GetCustomerFromDB()
var cust = AutoMapper.Mapper.Map<DBEntity.Customer, BizEntity.Customer>(dbCustomer);

// Update the property as per biz requirement
cust.Id = 53656;      // Fires the Notification

Let me know if this helps.
Regarding AutoMapper as a new library, this will be a minimum change and there's no licensing or learning curve required here to allow fast integration.

Upvotes: 0

Krzysztof Skowronek
Krzysztof Skowronek

Reputation: 2936

I would suggest using AutoMapper.

You can write another class with the same name and properties (with INPC), but in different namespace. Then, everytime you fetch database, you use Automapper to map the data into your notifiying class and everytime you save data to database you map it back.

That way you only need to change namespaces in code using your class and add code like this into your repository:

var dtos = args.Select(x => Mapper.Map<Zone>(x)).ToList();

Upvotes: 0

David
David

Reputation: 16277

The least intrusive way to do this might be using AOP patterns, for instance, using PostSharp framework: less than 2 lines of code!

[NotifyPropertyChanged]  //<---Add this attributes to the class
public class Zone 
{ 
    public Guid LocationId {get; set;}
    ...

}

To hook the changed event and add your own handler

//Zone instance;
((INotifyPropertyChanged) instance).PropertyChanged += ZoneOnPropertyChanged;

More details can be found here.


Update: the OP mentioned zero chance of integrating other library into the app, I am just curious, don't you use nuget? and what is the reason of this zero chance? In my personal view, you should, rather than NOT, to reinvent the wheels, if there is already a library which does the required features.

If licensing cost is the issue or it is overkill or to heavy to introduce this bulky library just for the sake of the problem, I think Fody, a free open source alternative to PostSharp can be considered. More specifically PropertyChanged.Fody package, which is very standalone, compact and light weight.

Upvotes: 2

Related Questions