Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

I find partial methods very useful, but there are no partial properties. Is there a good reason they were not included? What are my alternatives?

Tags:

c#

.net

UPDATE: Please note that I know I cannot do this...this is what I was really hoping could work. Maybe there is some other way that would separate responsibility, no? So what I am looking for is...

Entity Framework forces multiple responsibilities into the class (regular logic, basic annotations, and CRUD interface ability). I just want to take what would normally all be in one class...and separate the persistent ability of the class via Entity Framework and the regular logic.


MY THOUGHT PROCESS: Recently I have been getting into Entity Framework, but don't like the idea that some of the Entity classes are doing somewhat too much. Logic, interfacing with data access, and Entity Framework Annotations. To fix this, I wanted to make my Entity class file partial, and implement the data access functionality away from the other aspects of the class. This works well and is very clean!

While I was doing that, I figured it would be greatly beneficial to make my properties partial, and have the implementation away from the EF Property Annotations!! This would clear up the files and allow single responsibility. However, this is not allowed! Bummer.

The partial properties would be implemented just like partial methods. The definition in one partial property, and the implementation in the other partial property...just like the photos suggest (or the comments) in the link at the top, and the code below.

public partial class Agency : PropertyValidator, IAgency
{
    private string _name;

    public partial string Name 
    {
        get { return _name; }
        set
        {
            // PropertyValidator stuff
            if (string.IsNullOrEmpty(value))
                AddErrorToProperty("Agency name must contain a reasonable alphanumeric value.");
            if (string.IsNullOrWhiteSpace(value))   
                AddErrorToProperty("Agency name cannot contain all spaces.");

            SetPropertyIfValid(ref _name, value);
        }
    }
}

Then there is the other partial class that handles all abstract database items...

public partial class Agency : IPersitentEntity, IAgency
{       
    [Key]    // NOTE these Annotations are because of Entity Framework...nice separation! 
    public int ID { get; set; } // From IPersitentEntity

    [Required]
    [MinLength(3), MaxLength(50)]
    public partial string Name { get; set; } // IAgency NOTE this is not valid, but the 
                                             // separation is amazing!

    // From IPersitentEntity provide CRUD support
    public void Create() { throw new NotImplementedException(); }
    public void Retrieve(int id) { throw new NotImplementedException(); }
    public void Update(int id) { throw new NotImplementedException(); }
    public void Delete(int id) { throw new NotImplementedException(); }
}

Right now, I have to combine the Annotations and Logic together. It is kind of weird because I already separated out the abstract database items...except the EF Annotations!

like image 337
Christopher Rucinski Avatar asked Dec 05 '25 11:12

Christopher Rucinski


2 Answers

Part of the reason that there are no partial properties is that they don't fit into the basic design philosophy of partial members. The goal is to simply define a stub that a code generator could plug extra logic into if needed. If the code generated didn't fill in the method then all calls to the partial stub would be removed from the final program.

To meet this goal a partial method has some pretty limiting restrictions including that it must return void. This makes it very easy to compile away because there is no value that can remain if it is removed

SomePartialMethod();  

Properties on the other hand can never be void, they must be some concrete type. Hence the user can always write the following

string x = SomePartialProperty;

This is impossible for the compiler to completely erase. This expression must assign some value to x else the program simply can't compile. To make this work the compiler would likely have to pick an appropriate default value for x. It certainly could do this, (say default(T) but I imagine this factored into the decision to not have this feature.

like image 64
JaredPar Avatar answered Dec 07 '25 01:12

JaredPar


While partial is mainly for code generation, I have found it useful to separate out different responsibilities in the class that I have deemed not recommended to change my code base to facilitate that small level of separation on my own person projects. I have never seen that done in the field...again besides code generation.

I don't know if this is a personal project, but if it was, I would just use the partial like you have to separate out the persistent items. I have looked at websites that separate out this further by creating another level between the database code and the business logic. Implementing that can be a burdensome if you never did it before, and adds a good amount of classes to your project.

If this is a personal project, that might not be worth it, and if you want to "separate" out the different responsibilities, then partial classes your way does seem to work. If you need to change the way you access data, then you change that partial class only, no touching of the regular business logic.

[EDIT] But you are out of look with the separation of the Annotations on the properties most likely, but I wonder...

If you declared the properties in the persistent partial class, but called getter and setter private methods in the regular business logic partial class!?!? This way the logic is in that one partial class, and the Annotations will be in the other partial class where you want them


Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!