POCO - if POCO means pure .net class with only pro

2019-02-21 04:53发布

问题:

Very new to POCO, find some google links but found many different stories. Some connected with Entity framework, lazy loading etc. Some says its a pure .det class. Atleast MSDN.

LINK FOR DEFINE POCO FROM MSDN: msdn.microsoft.com/en-us/library/dd456872.aspx

I trust MSDN(a simple defination), and assume that it is a pure .NET Class.

Now let me come to the point. IF it is pure .net class with only properties inside it than it is equilateral to "MODEL" in MVC. example.

 [Required(ErrorMessage = "Full Name  required.")]
    [StringLength(20, ErrorMessage = "Username must be under 20 chars.")]
    public string UserName { get; set; }

    [Required(ErrorMessage = "Email required.")]
    [RegularExpression(".+@.+\\..+", ErrorMessage = "Email not valid.")]

    public string Email { get; set; }

    [Required(ErrorMessage = "PassWord required.")]
    [StringLength(20, ErrorMessage = "Maximum 20 chars. allow")]
    [DataType(DataType.Password)]
    public string Password { get; set; }

Upto this level it is clear to me. Now if i want to write my own validation (conditional) in MODEL using

ValidationAttribute or

IValidatableObject

this will be not pure .net class if i am not wrong. example.... (Something like below)

public class Wizard  : ValidationAttribute,IValidatableObject
{
    public override bool IsValid(object value)
    {
        return base.IsValid(value);
    }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        throw new NotImplementedException();
    }
    [Required(ErrorMessage = "Full Name  required.")]
    [StringLength(20, ErrorMessage = "Username must be under 20 chars.")]
    public string UserName { get; set; }

    [Required(ErrorMessage = "Email required.")]
    [RegularExpression(".+@.+\\..+", ErrorMessage = "Email not valid.")]

    public string Email { get; set; }

    [Required(ErrorMessage = "PassWord required.")]
    [StringLength(20, ErrorMessage = "Maximum 20 chars. allow")]
    [DataType(DataType.Password)]
    public string Password { get; set; }
}

Is this the POCO still? If yes, how can it contains methods.(opposite to MSDN link) IF NO, where should i write down my validation code (of course conditional validation in MVC). Looking for a really great answer with an example.

回答1:

POCOs mean you do not have to inherit from some framework defined base class in order to implement functionality. Basically you are free to design your class hierarchy.

You can add your own methods be it validation or some business logic.

A counter example would be to inherit from EntityObject class for entities in Entity Framework.



回答2:

The linked article doesn't say that POCO mustn't have methods. Clear description what POCO is can be found on Wikipedia:

... the term is used to contrast a simple object with one that is designed to be used with a complicated, special object frameworks such as an ORM component. Another way to put it is that POCOs are objects unencumbered with inheritance or attributes needed for specific frameworks.

POCO can have all methods or logic you need. The difference between POCO and non-POCO is that POCO is class you can use always even if you don't use specific framework (EF) but non-POCO can be used only when specific framework is linked or even worse initialized and used.

For purists data annotations violates POCO as well because they also demand specific API but in pragmatic approach data annotations are OK (except special annotations used in EF Code first to define mapping) because they bring dependency only to the way how entity is validated but not the dependency to the way how entity is persisted (non-POCO EF object). Dependency on persistence can demand reference to EF in assemblies where you never expect to use EF - for example presentation layer like MVC application.



回答3:

Personally I like to make my POCOs partial classes with the basic properties needed to define that model and then put and validation logic in a separate class. e.g:

public partial class Wizard
{
    public string UserName { get; set; }
    public string EmailAddress { get; set; }
}

and then if I wanted to add validation to UserName:

public partial class Wizard
{
    [Required]
    [StringLength(20)]
    public string UserName { get; set; }
}

I know the complier just amalgamates the two classes anyway and you may be repeating properties but I think its the cleanest approach.

Another option is to use the MetadataType attribute.