Call a method automatically via a partial class on . NET

Asked

Viewed 410 times

2

I created a partial class to the model users where I implemented some custom functions, such as a function that takes the assigned name and surname and generates a handle, see in the following example:

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 inserting a new instance in the database I always have to manually call the user.handle = user.makeHandle(), but I wish I could "overwrite" the method .add() or the model users whenever when creating a new instance and assigning values, the method makeHandle() is called automatically. It is possible to make this call directly 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");
}

The 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; }
    }
}

OBS: I renamed the method getHandle() for makeHandle() so that it does not generate a confusion... because the method now called makeHandle() should be called only in set; but in the get; the value returned is the same instantiated in the column handle table in the bank.

  • Have you tried putting users#getHandle in the constructor?

  • Yes, but in the constructor Handle turns empty because the variables first_name and last_name are filled after the constructor starts.

  • The estate Handle can receive any other value from a consumer of the class, or should it always be consented to the value assembled from the name + surname? Does the Handle, because it is a calculated value, shouldn’t it be read only for consumers of the class? And it is not quite certain that the set change the property in the instance and the get continue returning the value that was there before (value of the bank at the time of obtaining the entity).

3 answers

5


Specifically answering the question asked, as far as I know, with the Add() is not possible. I know that can touch the SaveChanges(), but then it’s too late.

The ideal would be to actually have a reactive form of a change in one of the entity’s properties already generate the change in ownership handle. It would be possible to create properties FirstName and LastName in place of first_name and last_name. But I wouldn’t have been able to prohibit the use of these.

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

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

I put in the Github for future reference.

Alternatives

If you still want to tinker with the properties in time after the entity’s manipulation, you may have a way out.

Talking to the Gypsy at chat he talked about the interface IValidatableObject. 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 also to change some member of the entity, keeping the status valid.

Example of implementation in response in the OS.

I also talked about the possibility of creating a repository that overlaps the existing one in EF, but it does not seem to me a good solution. If you do this, you can control everything you can do at any time, but you would have to recreate something already existing and that must be why you decided to use EF, not to recreate it.

It seems to me that solution would solve better what was asked before by the AP.

2

You must be explicit to fire that handler. Now, the location where he’s being shot is that it should be centered. Otherwise you will have to make a call like this each time you change the properties of this object.

Notably you are using classes created automatically by some kind of reverse engineering to create your models and other entities. I believe this is why you are having difficulties in giving some maintenance.

I have an example on Github on how to build layered applications for responsibility.

I believe it can help you get more control of your application codes, and it will also greatly reduce your post-deployment maintenance cost.

MVC Music Store - Github

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

2

Don’t forget that your property Handle has a getter, where you can write any code, including by doing this getter return function result makeHandle():

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

Simple, no?

There are several other options, such as building the Handle to the extent that 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. Work only with the getters and setters is simpler.

  • @Rafaelalexandre now you can touch the property or still can not touch it?

  • Yes, now I can.

  • @Rafaelalexandre should have put this in the question. I find it strange that now I can, but I’ll go to yours, I’ll edit my answer just to reinforce what I’ve already answered.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.