In a c# project (and MVC project to be exact) I have some partial classes. Some of those classes have DateTime properties and I need to expand their functionality a bit. The thing I'm doing is adding a helper property to the class that let's me alter the time separately.
So if I have a SomeDate property in the generated partial class I would add this to the not generated part of the class:
DateTime? _someDateTime;
[DataType(DataType.Time)]
public DateTime? SomeDateTime
{
get
{
if (_someDateTime == null)
{
if (SomeDate.HasValue)
{
_someDateTime = SomeDate;
}
}
return _someDateTime;
}
set
{
_someDateTime = value;
}
}
With some extra code elsewhere I can easily enough manipulate the time of SomeDate property in the way that I want.
Now I would need to have similar helper properties related to other properties in this and other partial classes. Is there some alternative to copy-pasting the code above?
P.S. After writing this question, some ideas started forming in my mind. They involve inheriting from DateTime and writing a new attribute that does nothing but provide name of the related DateTime property.
There are multiple approaches to do that:
As you already stated: create a wrapper class which provides the functionality you need which manipulates the state of the object
Similar to the first one, create an extension method which then manipulates a DateTime instance
Create a "Helper" class, which is able to change a DateTime instance
It really depends on the context of your code as well on the requirements, constraints, etc.
Related
I seem to understand the reason behind taking help of MetadataTypeAttribute to Add Validation to the Model in case of Database First as we want to avoid the changes being overwritten when the model is generated from the database next time.
I've noticed few people defining validation using MetadataType even when they're using Code First approach and there is no chance of their Entity Classes being overwritten by some kind of auto-generation of code.
Does it make any sense to not apply these DataAnnotations on the actual Entity class directly and instead, separate these into partial class definitions and then link using MetadataType, even when using Code First approach to define Entity Model?
public class MyEntity
{
[Required]
public string Name { get; set;}
}
vs
public partial class MyEntity
{
public string Name { get; set;}
}
[MetadataType(typeof(MyEntityMetadata))]
public partial class MyEntity
{
}
public class MyEntityMetadata
{
[Required]
public string Name { get; set;}
}
Does it make any sense to not apply these DataAnnotations on the actual Entity class directly and instead, separate these into partial class definitions and then link using MetadataType, even when using Code First approach to define Entity Model?
In most of the cases it doesn't make sense because it involves unnecessary and redundant code duplication just to associate some attributes with the properties.
It doesn't make sense if the entity class model is created by you with code.
It also doesn't make sense if it's created with some custom code generation you have control over (like T4 template) because you can customize the generation itself.
The only case when it makes sense is when you have no control over the entity class code (for instance, the class coming from 3rd party library). In such case, you can use AssociatedMetadataTypeTypeDescriptionProvider class to associate metadata with the 3rd party class.
For instance, let say the following class is coming from another library with no source code:
public sealed class ExternalEntity
{
public string Name { get; set;}
}
Then you can define the metadata class:
public class ExternalEntityMetadata
{
[Required]
public string Name { get; set;}
}
and associate it with the ExternalEntity using TypeDescriptor.AddProvider method once (during the application startup or something):
TypeDescriptor.AddProvider(new AssociatedMetadataTypeTypeDescriptionProvider(
typeof(ExternalEntity), typeof(ExternalEntityMetadata),
typeof(ExternalEntity));
It really makes sense to create a class and use it many times. In code first approach you need data validation which is possible to implement by using data annotations and When you have many props with the same features your life will be easier by doing so. It is not just about overwriting and in this case it has some other reasons. Hope to understand your question well and my answer is appropriate.
I think the questions is where is the difference between data annotations on model and on code first.
So at first you have data validation
this is setting up attributes on your code first model
and this sets up configuration of database columns and this will set the size and restrictions on your data model. (this once populated usually does not change without migrating data.)
Model validation
model validation is your model you are binding your form into.
This model would contain more information for your UI.
I don't know why you are trying to employ a Database first technique to a more complete, say, Code first since you can create ViewModels to meet your purpose. Also not all the data annotations are supported in Entity Framework.
MetadataType limitations
It cannot be applied to a property and can be only be applied to a
single class for each class type.
This attribute cannot be inherited, so you cannot customize it.
On the other side, this attribute can be applied to partial class
which is the main purpose of this attribute.
This attribute will be respected by ASP.NET MVC but will not be read
by Entity Framework.
Cons of using MetadataType
you have to use ViewBag, ViewData or something else to pass
additional information to the view
Your design is less testable since it relies on a static object
mechanism.
It is also not required and someone could omit it without breaking
anything.
It also means that you are splitting your model class into 3 files.
One generated, one of yours and one with attributes.
If you want to add attributes to existing properties in a class (partially) :
This may work or be ignored by the EF, test it:
public partial class YourModelClass
{
public string YourProperty{get;set;}
}
//Your Partial Class
[MetadataType(typeof(YourModelClassMetaData))]
public partial class YourModelClass
{
}
//The class that adds your attributes
public class YourModelClassMetaData
{
[Required]
public object YourProperty{get;set;}
}
I've been agaonizing about this problem for some days:
I have a class Info
public class Info
{
private int _no;
public int No
{
get
{
return _no;
}
set
{
_no = value;
}
}
}
That class can be used anywhere in any classes (inherited or as property). The property can be considered as security relevant or not. That information is known at design time and needs to be stored for that particular property.
So for some classes which uses that class as property I want the member "No" to be set accordingly.
public class IsRelevant
{
private Info _prop = new Info();
public Info Prop { get { return _prop; } set { _prop = value; } }
}
public class IsNotRelevant
{
private Info _prop = new Info();
public Info Prop { get { return _prop; } set { _prop = value; } }
}
For a first try I was thinking about introducing an custom attribute like this:
[SecurityRelevant(RelevantLevel = SecurityRelevant.SecurityRelevant_Level1, IsRelevant = true)]
And then once I instanciate the class "IsRelevant", I will go through the properties and its classes and set the custom attribute as desired:
IsRelevant.Prop.No => IsRelevant = true,
eg IsNotRelevant.Prop.No => IsRelevant=false.
But as far as I understood the meta information (attributes) for a class is an instance created once for each type. So if I change the values of the custom attribute I will change it for all instances of that class (because it's bound to that type!?)
Edit: This can't be done as stated here: Change Attribute's parameter at runtime Everytime you access the custom attributes, a new instance with the default values will be created. Changes to that attribute won't be stored there.
A second approach was to store that information in an external class and save all the model paths etc. I don't like that because the information belongs to a specific class.
The third approach was to implement an interface which holds a dictionary which stores that information:
public interface ISecRelevant
{
Dictionary<PropertyInfo, bool> SecInfo { get; set; }
}
and then every class which has a security relevant property would need to implement it.
On every instantiation of that class, the information needs to be added in the dicationary. This is the best solution I came up with yet. The class which holds the information doesn't necessarily needs to be a dictionary because in a second step I want to ask an instance with a potential security relevant property if it really is relevant. So I could just pass that property in a method of that "security relevant information container" and ask if the property is relevant.
So I'm basically asking if someone has a better idea to store that information or to access it, because somehow I still don't like the solution.
So here are some general conclusions about that problem:
The information whether a property is security relevant is not really a runtime information, but available upfront. So ideally I would like to store it in a "static" way
The information is best to be attached to the property, at least to the parent class, because only it should know about that information, not any other class which uses that Info class to avoid coupling
There are many more security relevant properties which are scatterd over a lot more classes. These are also used in a more deeper and complex object hierarchy, but I thought it basically comes down to the problem I described here.
Edit: Since I did not come up with a better idea, I implemented the third solution, but with a string for the property name. But then I stumbled into another problem when using Lists. What happens if you have a List as property with a type that has a sec-relevant property? The List would have to know where it is sitting to enable adding the information to every instance which is inserted in the List...
While searching I found another post, basicallay asks for the same thing: C# - add some meta data associated to a particular field when I am assigning a value to the field of a class?
He suggests to implement a base class which hold that kind of information. This will work for "normal" properties. But not for the list-case.
Further explanation and example:
I thought the example with "security relevant" was helping you guys to understand the problem, but maybe it just confused you. Simply said: I need to attach meta information a any property of a class (and also to the items which are maybe contained in a list). Where I need to put this information is known at design-time but is dependent on the instanciation of the classes. So it DOES matter who is instanciating the class. This is also the reason why I cant use static information.
Here is an example:
Class A {
public int MetaProperty; // (this it the propert where i might want to add meta info)
}
Class B {
public A ThePropertyWithMetadata;
}
Class C{
public A TheProperty;
}
Whenever I create an instance of class B, I need to attach meta information to
InstanceOfB.ThePropertyWithMetadata.MetaProperty
On the other hand whenever I create an instance of class C, I DO NOT want to to attach any meta information to that property. I want to show that meta info in the user interface and give the user more information about that property.
So I do know when to assign the meta information, but cant put it in the classes at design time. Hope this clarifies it now :-)
Let's say I have a POCO with the following:
[DataMember]
public Nullable<int> MetricId
{
get { return _metricId; }
set
{
if (_metricId != value)
{
_metricId = value;
OnPropertyChanged("MetricId");
}
}
}
private Nullable<int> _metricId;
I want to validate that the MetricId is strictly greater than 0
Obivously, if I put this rule as a data annotation in this class it will be overwritten the next time I regen the poco. Where do I put this logic?
Thanks!
I seem to remember the suggestion being to utilize partial classes and roll a partial class that implemented the logic you didn't want to be overwritten.
After reading the comments and responses, it seems that creating another class is fine, but by making it partial, it ties my business logic directly to the Entity Framework and the generated POCO code. This is worrisome because as EF4 changes into EF5 and the T4 template changes to the T5 template what will happen to my code? Plus I just don't feel comfortable using partial classes as normal classes.
Instead, and someone can still provide a better answer (please do), I think creating a framework independent object (one not tied to EF) is better. Then I can map it to a generic business object. Something like:
static Customer Map(CustomerPOCO poco)
{
return new Customer
{
CustomerId = poco.CustomerId
...
...
};
}
It's not clean using partial classes lets say you have product abstract lass and derived classes online product and store product. Both inherit price property but price is different. And let's say business logic may be different too. Now you got two additional classes that you don't really need. In larger system, it multiplies.
I'm displaying Business Object in generic DataGrids, and I want to set the column header through a custom attribute, like:
class TestBo
{
[Header("NoDisp")]
public int ID {get; set;}
[Header("Object's name")]
public String Name { get; set; }
}
So far, so good, but I'd also want to separate my display from my data, by inheritance:
class TestBO
{
public int ID {get; set;}
public String Name { get; set; }
}
class TestPresentationBO : TestBO
{
//Question: how to simply set the Header attribute on the different properties?
}
I see a solution via reflection with a SetCustomAttribute in the Child constructor, but it will be cumbersome, so is there a simple and elegant trick for this problem?
Please prevent me from breaking the data/presentation separation ;o)
Question: how to simply set the Header attribute on the different properties?
There is no way to set an attribute on an inherited member the way you have suggested, since attributes are specific to a type. SetCustomAttribute won't help you - it's only any good when you construct new types at runtime. Once an attribute has been compiled in you cannot change it at runtime, since it's part of the metadata.
If you want to maintain the separation you will have to find another way.
(You could make the properties virtual, override them in the Presentation class and add attributes on the overrides, but this looks dodgy and doesn't really separate anything - you end up with a complete TestBO class in your TestPresentationBO anyway...)
Make the properties in TestBo virtual and override them in TestPresentationBO. That way you can add the attributes.
Just thinking, can't you solve this with partial classes and the MetadatatypeAttribute? MVC2 uses this pattern for Model validation.
You can do it like WCF RIA Services. Add an attribute to TestBO, like [Presentation] taking a type as parameter. This new type will redefine the properties, but with the presentation attributes.
At run-time, you have to get the identity of the new type and get the custom attributes of its properties.
Or forget about the attribute and have a dictionary mapping the BO with the presentation BO class. This presentation BO class does the same thing as above, i.e. redefine properties with custom attributes.
the presentation BO class is never instantiated, it is simply reflected upon to get presentation info.
Are you using the MVVM (model view view-model) pattern? It seems to me, and partly from the other answers, that you can't really do this with the custom attributes like you want. But, it also seems to me that your TestPresentationBO is really just like a "View Model" for TestBO. A view model is basically a sort of wrapper or surrogate for a business or logic class--which is basically what you want. (This summary of a view model may not be 100% accurate; I'm just starting out with MVVM myself.)
You can create a TestBOViewModel to wrap TestBO, then pass the collection of TestBOViewModel to the datagrid. Of course, you can decorate the properties exposing the wrapped class with [Header("Object's name")] etc. This doesn't use inheritance, but I don't see why you'd need to use inheritance in this situation. Using a view model, does, however, cleanly separate your presentation (view) from your data (model) by using the wrapper (view model).
For more info on the MVVM pattern, I found this to be an interesting read: WPF Apps With The Model-View-ViewModel Design Pattern.
Something like this. Of course, you can add validation and other goodies in here too.
public class TestBOViewModel // extend from DependencyObject
{ // if you want to use dependency properties
private TestBO _myBO;
public TestBOViewModel(TestBO bo)
{
_myBO = bo;
}
[Header("NoDisp")]
public int ID
{
get { return _myBO.ID; }
set { _myBO.ID = value; }
}
}
For C# 6.0 you can easily hide inherited members and introduce your own attributes. This might, however, hide any attributes on the original property. Also this simplified syntax makes the property read-only, so you might need to pipe the get/set yourself.
public class User
{
public string Login { get; set; }
}
public class UserDetail : User
{
[Display(Name = "Login:")]
public new string Login => base.Login;
}
I'm a bit confused on the point of Automatic properties in C# e.g
public string Forename{ get; set; }
I get that you are saving code by not having to declare a private variable, but what's the point of a property when you are not using any get or set logic? Why not just use
public string Forename;
I'm not sure what the difference between these 2 statements is, I always thought you used properties if you wanted additional get/set logic?
Properties can have code put into them without breaking contract, fields can't have code put into them without changing them to properties (and breaking the interface). Properties can be read only or write only, fields can't. Properties can be data bound, fields can't.
You can write
public string Forename{ get; private set; }
to get read-only properties... Still not nearly as versatile as real properties, but it's a compromise that for some works.
I'm not sure what the difference between these 2 statements is, I always thought you used properties if you wanted additional get/set logic?
In the first case, the compiler will automatically add a field for you, and wrap the property. It's basically the equivalent to doing:
private string forename;
public string Forename
{
get
{
return this.forename;
}
set
{
this.forename = value;
}
}
There are many advantages to using properties over fields. Even if you don't need some of the specific reasons, such as databinding, this helps to future-proof your API.
The main problem is that, if you make a field, but in v2 of your application, need a property, you'll break the API. By using an automatic property up front, you have the potential to change your API at any time, with no worry about source or binary compatibility issues.
It is meant that you expect to add the logic later.
If you do so and have it as property from the beginning, you will not have to rebuild the dependent code. If you change it from a variable to a property, then you will have to.
Consider looking at some related threads about Difference Between Automatic Properties and Public Fields, Fields vs Properties, Automatic Properties - Useful or Not?, Why Not to Use Public Fields.
Public data members are evil (in that the object doesn't control modification of it's own state - It becomes a global variable). Breaks encapsulation - a tenet of OOP.
Automatic properties are there to provide encapsulation and avoid drudgery of writing boiler plate code for simple properties.
public string ID { get; set;}
You can change automatic properties to non-automatic properties in the future (e.g. you have some validation in a setter for example)... and not break existing clients.
string m_ID;
public string ID
{
get { return m_ID; }
set
{
//validate value conforms to a certain pattern via a regex match
m_ID = value;
}
}
You cannot do the same with public data attributes. Changing a data attribute to a property will force existing clients to recompile before they can interact again.
When adding auto properties the compiler will add get set logic into the application, this means that if you later add to this logic, and references to your property from external libraries will still work.
If you migrated from a public variable to a property, this would be a breaking change for other libraries that reference yours - hence, why not start with an auto property? :)
For one, you can set the property to virtual and implement logic in an inheriting class.
You can also implement logic in the same class afterwards and there won't be side-effects on any code relying on the class.
Not all properties need get/set logic. If they do, you use a private variable.
For example, in a MV-something pattern, your model would not have much logic. But you can mix and match as needed.
If you were to use a field like you suggested in place of a property, you can't for example define an interface to describe your class correctly, since interfaces cannot contain data fields.
A property is like a contract, and you can change the implemenation of a property without affecting the clients using your classes and properties. You may not have any logic today, but as business requirements change and if you want to introduce any code, properties are your safest bet. The following 2 links are excellent c# video tutorials. The first one explains the need of properties over just using fields and the second video explains different types of properties. I found them very useful.
Need for the Properties in C#
Poperties in C#, Read Only, Write Only, Read/Write, Auto Implemented
Take a look at the following code and explanation.
The most common implementation for a property is getter or a setter that simply reads and writes to a private field of the same type as a property. An automatic property declaration instructs the compiler to provide this implementation. The compiler automatically generates a private backing field.
Look into the following code:-
public class Stock
{
decimal currentPrice ; // private backing field.
public decimal CurrentPrice
{
get { return currentPrice ; }
set { currentPrice = value ; }
}
}
The same code can be rewritten as :-
public class Stock
{
public decimal CurrentPrice { get ; set ; } // The compiler will auto generate a backing field.
}
SOURCE:- C# in a Nutshell