Call a method automatically via a class class in .NET

2

I created a partial class for the model users where I implemented some custom functions, such as a function that takes the first and last name assigned and generates a handle , see example below:

namespace E_Learning.Models
{
    using System;
    using System.Collections.Generic;
    using E_Learning.Helpers;

    public partial class users
    {
        public string makeHandle()
        {
            return Slugify.Make(this.first_name + ' ' + this.last_name);
        }

        public string full_name
        {
            get
            {
                return this.first_name + ' ' + this.last_name;
            }
        }

        private Nullable<int> age
        {
            get
            {
                DateTime now = DateTime.Today;

                if (this.birthday.HasValue)
                {
                    DateTime birthday = DateTime.Parse(this.birthday.ToString());
                    int age = now.Year - birthday.Year;

                    if (now < birthday.AddYears(age))
                        age--;

                    return age;
                }

                return null;
            }
        }
    }
}

Simple thing. But when I insert a new instance in the database I always have to manually call user.handle = user.makeHandle() , but I'd like to be able to "override" the .add() or the model users method for whenever creating a new instance and assign the values, the makeHandle() method is called automatically. Is it possible to make this direct call from partial class ?

public ActionResult Index(Entities db)
{
    string password = BCryptHelper.HashPassword("admin", BCryptHelper.GenerateSalt(8));

    users user = new users
    {
        first_name = "Rafael",
        last_name = "Alexandre",
        email = "[email protected]",
        password = password,
    };

    user.handle = user.makeHandle();
    db.Set<users>().Add(user);
    db.SaveChanges();

    return View("~/Views/Index.cshtml");
}

O Model:

namespace E_Learning.Models
{
    using System;
    using System.Collections.Generic;
    using E_Learning.Helpers;

    public partial class users
    {
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
        public users()
        {
            this.signatures = new HashSet<signatures>();
            this.testimonials = new HashSet<testimonials>();
        }

        public int id { get; set; }
        public string identity_ { get; set; }
        public string first_name { get; set; }
        public string last_name { get; set; }
        public string email { get; set; }
        public string telephone { get; set; }
        public string password { get; set; }
        public Nullable<System.DateTime> birthday { get; set; }
        public Nullable<int> sexuality { get; set; }
        public string remember_token { get; set; }
        public System.DateTime updated_at { get; set; }
        public System.DateTime created_at { get; set; }
        public Nullable<byte> status { get; set; }
        public string handle { get; set; }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
        public virtual ICollection<signatures> signatures { get; set; }
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
        public virtual ICollection<testimonials> testimonials { get; set; }
    }
}

NOTE: I renamed the getHandle() method to makeHandle() so it does not cause confusion ... because the method now called makeHandle() should only be called in set; but in get; the value returned is the same instantiated in the column handle of the table in the bank.

    
asked by anonymous 04.05.2016 / 17:13

3 answers

4

Responding specifically to the question asked, as far as I know with Add() is not possible. I know can play with SaveChanges() . But then it's too late.

The ideal would really be to have a reactive form of a change in one of the entity's properties already generating the change in the handle property. It would be possible to create FirstName and LastName properties instead of first_name and last_name . But I could not forbid the use of these.

As the AP now says (in comment) that this is possible, then the best solution is to change the existing properties so that they manipulate the property, there instead of an automatic property, you can define the behavior that it should Tue. This goes against what was asked, after all why use partial class if you can tinker with the property code?

private string _first_name;
public string first_name { 
    get { return _first_name; }
    set { 
        _first_name = value; 
        handle = getHandle(); 
    }
}
private string _last_name;
public string last_name { 
    get { return _last_name; }
    set { 
        _last_name = value; 
        handle = getHandle(); 
    }
}

Alternatives

If you still want to tweak the properties in time after the entity manipulation, you may have an exit.

Chatting with Gypsy in chat he talked about the < a% s% s. You can use this opportunity to validate the object to write to the property automatically. Normally this would be used only to validate, but nothing prevents it from being used to change any member of the entity, keeping the state valid.

Example of implementation in response in OS .

Also in the chat conversation, you talked about the possibility of creating a repository that overlaps with the existing one in EF. But it does not seem like a good solution. If you do this, you can control everything you can do at any given time, but you would have to re-create something already existing and that is why you decided to use EF, not to recreate it.

I think the solution would be to better resolve what asked before by AP .

    
04.05.2016 / 17:37
2

You must be explicit to fire this handler . Now the place where it is being fired is that it should be centralized. Otherwise, you'll have to make a call every time you change the properties of that object.

Remarkably, you are using classes automatically created by some kind of reverse engineering to create your models and other entities. I think that's why you're having a hard time giving some maintenance.

I have an example in GitHub on how to build layered applications by responsibility.

I think it can help you get a better control of your application codes, and it will also greatly reduce the cost of post-deployment maintenance.

MVC Music Store - GitHub

ASP.NET MVC Implementing DDD, SOLID , DI, IOC and SelfValidation

    
04.05.2016 / 17:32
2

Do not forget that your handle property has a getter , where you can write any code, including doing this getter return the result of the makeHandle () function:

public string handle 
{ 
    get { return makeHandle(); }
}

Simple, is not it?

There are several other options, such as constructing handle as the properties involved are set, for example:

private string _first_name;
public string first_name 
{ 
    get { return _first_name; }
    set
    { 
        _first_name = value; 
        handle = makeHandle(); 
    }
}

private string _last_name ;
public string last_name 
{ 
    get { return _last_name; }
    set
    { 
        _last_name = value; 
        handle = makeHandle(); 
    }
}

There seems to be no need to involve the Entity Framework in this. Working only with getters and setters is simpler.

    
04.05.2016 / 18:18