If a type satisfies the implementation of an interface should it 'implement' it? - interface

I have this interface
public interface IWeighted {
int Weight { get; }
}
and this attribute
[AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
public class WeightAttribute : Attribute {
private readonly int m_Weight;
public int Weight => m_Weight;
public WeightAttribute(int weight = 1) {
m_Weight = weight;
}
}
Should WeightAttribute implement IWeighted as it exactly matches the contract declared within IWeighted, or should it not seeing as WeightAttribute is an attribute (intended for use on enum members alone) and as such should not be target to selection itself?

Related

How to use an interface property set by one class and get the same in another class?

`I have two classes, Class A and Class B inherited from Interface IA which has a property int count with get and set. How do I set that property value in one class and use the same value in another class?
I might not have written complete code here its just a sample one here:
public interface IA
{
int count
{
get;
set;
}
}
public class A: Class X,IA
{
private int _count;
public int count
{
get => _count;
set =>_count = value;
}
this.Count= 1;
}
public class B: Class Y,IA
{
private int robot1AvailableQue;
private int _count;
public int count
{
get => _count;
set =>_count = value;
}
if (count == 1)
{
spaceAvailable= true;
}
}

Deserialize the immutable class with the custom constructor

I have a public class with some public immutable properties (only get;). It also has a custom constructor, which takes one additional parameter, required not for the setting of a property, but only for the calculations. I think, because of that, this class cannot be deserialized properly via Newtonsoft Json.
Other classes with only corresponding input parameters to the properties work fine.
So, this class deserializes itself not properly, returning zeros. It has additional parameter 'value' which is not related to any property, and just used for a calcualtions and presenting the data.
public class DurationData
{
public DateTime Start { get; }
public int Index { get; }
public double ActivityDurationInHours { get; }
public string Activetime { get; }
public ShiftDurationData(DateTime start, int index, TimeSpan value )
{
Start = start;
Index = shiftIndex;
ActivityDurationInHours = Math.Round(value.TotalHours, 1);
Activetime = $"{(int)value.TotalHours:d2}:{value.Minutes:D2}:{value.Seconds:D2}";
}
}
if I set the mock of this like below or just with mutable properties (get;set) and without a constructor it deserializes itself properly.
public class DurationData
{
public DateTime Start { get; }
public int Index { get; }
public double ActivityDurationInHours { get; }
public string Activetime { get; }
public ShiftDurationData(DateTime start, int index, double activityDurationInHours, string activeTime)
{
Start = start;
Index = shiftIndex;
ActivityDurationInHours = activityDurationInHours
ActiveTime = activetime ?? throw new ArgumentNullException(nameof(activeTime))
}
}
But I don't wan't to create additional mock class and would like to work with original. How to do this properly

Can I use reflection to find aspects produced by multicast?

I have a case where an aspect CanBeDependedUpon on class A is multicast to the properties of class A. However when inspecting class A from aspect DependsOn, I do not find CanBeDependedUpon on the properties of Y. Is this correct PostSharp behavior?
[CanBeDependedUpon]
class A
{
public bool Foo
{
get;
set;
}
[DependsOn("Foo")]
public bool Bar
{
get;
set;
}
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Property, AllowMultiple = true)]
[MulticastAttributeUsage(MulticastTargets.Class | MulticastTargets.Struct | MulticastTargets.Property, PersistMetaData = true, AllowMultiple = true)]
class CanBeDependedUpon : Aspect
{
}
class DependsOn : Aspect
{
private string _target;
public DependsOn(string target)
{
_target = target;
}
public override bool CompileTimeValidate(object target)
{
//validate that the target property exists and is annotated with X.
return base.CompileTimeValidate(target);
}
}
By default, PostSharp removes the attribute once the aspect has been applied to your code. You can explicitly instruct PostSharp to retain the attributes if you want to look them up using reflection.
For this, you need to apply MulticastAttributeUsage attribute to your class and set PersistMetaData to true.
[MulticastAttributeUsage( MulticastTargets.Class, PersistMetaData = true )]
This use case is documented here: http://doc.postsharp.net/multicast-reflection

How to get a property name of a given type strongly typed revisited?

How can I simplify the code below to avoid to pass the object for type inference on the generic method?
using System;
using System.Linq.Expressions;
namespace lambda
{
class Program
{
static void Main(string[] args)
{
var area = new Area { Name = "New Area" };
var propertyName = area.GetPropertyName(area, a => a.Name); // propertyName is COMPILE time checked
Console.WriteLine(propertyName);
}
}
public class Area
{
public int Id;
public string Name { get; set; }
}
public static class Extension
{
public static string GetPropertyName<T>(this Area entity, T e, Expression<Func<T, object>> path) // T e for type inference
{
var member = path.Body as MemberExpression;
if (member == null) throw new ArgumentException();
return member.Member.Name;
}
}
}
I mean instead of calling the extension method with area.GetPropertyName(area, a => a.Name)
just do a call like this area.GetPropertyName(a => a.Name), avoid to pass there area object just for type inference
I guess that I can’t do unless I refactor the signature of the method to GetPropertyName(this IEntity entity, Expression> path)
But in that case will be less obvius want I want at code writing time since I will need to specify the type on every call
I mean area.GetPropertyName( a => a.Name) seems to bel for me less clear writing code than writing area.GetPropertyName(area, a => a.Name)
The example code below works fine with asked requirements, no need to pass the object itself for type inference when calling the extension method
I used a base class and an interface that for my case works fine for all my domain class.
See code below
namespace UnitTestProject
{
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Linq.Expressions;
public interface IEntity<T>
{
}
public abstract class Entity<T> : IEntity<T> where T : class
{
}
public class Area : Entity<Area>
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime Created { get; set; }
public bool Closed { get; set; }
public string Description { get; set; }
}
public static class EntityExtension
{
public static string GetPropertyName<T>(this IEntity<T> entity, Expression<Func<T, object>> expr) // T e for type inference
{
var unary = expr.Body as UnaryExpression;
var member = expr.Body as MemberExpression;
return member != null ? member.Member.Name : (unary != null ? ((MemberExpression)unary.Operand).Member.Name : String.Empty);
}
}
[TestClass]
public class UnitTest
{
[TestMethod]
public void GetPropertyName_Tests()
{
var area = new Area();
var x = area.GetPropertyName(a => a.Id);
var y = area.GetPropertyName(a => a.Name);
var v = area.GetPropertyName(a => a.Created);
var w = area.GetPropertyName(a => a.Closed);
var z = area.GetPropertyName(a => a.Description);
Assert.AreEqual(x, "Id");
Assert.AreEqual(y, "Name");
Assert.AreEqual(v, "Created");
Assert.AreEqual(w, "Closed");
Assert.AreEqual(z, "Description");
}
}
}

Dynamic way to Generate EntityTypeConfiguration : The type 'TResult' must be a non-nullable value type

I was thinking to generate EntityTypeConfiguration dynamically from run time and i don't want any EF dependency in Models[That is why i avoid Data Annotation].
So I declare a custom attribute(or can be any configuration file later on)
[AttributeUsage(AttributeTargets.Property, AllowMultiple=true )]
public class PersistableMemberAttribute : Attribute
{
public bool Iskey;
public bool IsRequired;
public bool IsIgnored;
public bool IsMany;
public string HasForeignKey;
public bool PropertyIsRequired;
public bool PropertyIsOptional;
}
And here is one of my Models is look like:
public class Blog
{
[PersistableMember(Iskey=true)]
public Guid BlogId { get; set; }
[PersistableMember(PropertyIsRequired = true)]
public string Name { get; set; }
public string Url { get; set; }
[PersistableMember(IsIgnored=true)]
public int Rating { get; set; }
[PersistableMember(IsMany =true)]
public ICollection<Post> Posts { get; set; }
}
Now I am going to write a generic EntityTypeConfiguration , which will create the configuration dynamically on run time based on the attribute values :
public class GenericEntityConfiguration<T> : EntityTypeConfiguration<T> where T : class
{
public GenericEntityConfiguration()
{
var members = typeof(T).GetProperties();
if (null != members)
{
foreach (var property in members)
{
var attrb= property.GetCustomAttributes(typeof( PersistableMemberAttribute ),false).OfType<PersistableMemberAttribute>();
if (attrb != null && attrb.Count() > 0)
{
foreach (var memberAttributute in attrb)
{
if (memberAttributute.Iskey || memberAttributute.IsIgnored)
{
var entityMethod = this.GetType().GetMethod("Setkey");
entityMethod.MakeGenericMethod(property.PropertyType)
.Invoke(this, new object[] { property, memberAttributute });
}
if (memberAttributute.IsRequired)
{
var entityMethod = this.GetType().GetMethod("SetRequired");
entityMethod.MakeGenericMethod(property.PropertyType)
.Invoke(this, new object[] { property, memberAttributute });
}
if (memberAttributute.PropertyIsRequired || memberAttributute.PropertyIsOptional)
{
var entityMethod = this.GetType().GetMethod("SetPropertyConfiguration");
entityMethod.MakeGenericMethod(property.PropertyType)
.Invoke(this, new object[] { property, memberAttributute });
}
}
}
}
}
}
public void SetPropertyConfiguration<TResult>(PropertyInfo propertyInfo, PersistableMemberAttribute attribute)
{
var functorParam = Expression.Parameter(typeof(T));
var lambda = Expression.Lambda(
Expression.Property(functorParam, propertyInfo)
, functorParam);
if (attribute.PropertyIsRequired)
{
this.Property<TResult>((Expression<Func<T, TResult>>)lambda).IsRequired();
}
if (attribute.PropertyIsOptional)
{
this.Property<TResult>((Expression<Func<T, TResult>>)lambda).IsOptional();
}
}
public void Setkey<TResult>(PropertyInfo propertyInfo, PersistableMemberAttribute attribute)
{
var functorParam = Expression.Parameter(typeof(T));
var lambda = Expression.Lambda(
Expression.Property(functorParam, propertyInfo)
, functorParam);
if (attribute.Iskey)
{
this.HasKey<TResult>((Expression<Func<T,TResult>>)lambda);
}
if (attribute.IsIgnored)
{
this.Ignore<TResult>((Expression<Func<T, TResult>>)lambda);
}
}
public void SetRequired<TResult>(PropertyInfo propertyInfo, PersistableMemberAttribute attribute) where TResult : class
{
var functorParam = Expression.Parameter(typeof(T));
var lambda = Expression.Lambda(
Expression.Property(functorParam, propertyInfo)
, functorParam);
if (attribute.IsRequired)
{
this.HasRequired<TResult>((Expression<Func<T, TResult>>)lambda);
}
}
}
But i got the compilation error of
Error 1 The type 'TResult' must be a non-nullable value type in order to use it as parameter 'T' in the generic type or method 'System.Data.Entity.ModelConfiguration.Configuration.StructuralTypeConfiguration.Property(System.Linq.Expressions.Expression>)' D:\R&D\UpdateStorePOC\UpdateStorePOC\Data\GenericEntityConfiguration.cs 63 17 UpdateStorePOC
which for these two statements:
this.Property<TResult>((Expression<Func<T, TResult>>)lambda).IsRequired();
this.Property<TResult>((Expression<Func<T, TResult>>)lambda).IsOptional();
that means that I need to put a constraint on my method to restrict it to a value type. In C#, this is done with the ‘struct’ keyword.
public void SetPropertyConfiguration<TResult>(PropertyInfo propertyInfo, PersistableMemberAttribute attribute) Where TResult : struct
But Its not the solution since my property type can be a class e.g string or int, bool double, etc . So it is not at all clear that I can send them into this method. Please help me to solve this issue whether there is any other way to do it.
I don't want any EF dependency in models.
With fluent mapping you're almost there and you won't come any closer. Your attributes, even though intended to be moved to a configuration file, don't make your model any more free of any EF footprint.1 Worse, they only add a second mapping layer (if you like) between your model and EF's mapping. I only see drawbacks:
You still have to maintain meta data for your model, probably not any less than regular fluent mapping and (probably) in awkward manually edited XML without compile-time checking.
You will keep expanding your code to cover cases that EF's mapping covers but yours doesn't yet.2 So it's a waste of energy: in the end you'll basically have rewritten EF's mapping methods.
You'll have to keep your fingers crossed when you want to upgrade EF.
With bugs/problems you're on your own: hard to get support from the community.
So my answer to your question help me to solve this issue would be: use fluent mapping out of the box. Keep it simple.
1 For example, you would still have to use the virtual modifier to enable proxies for lazy loading.
2 Like support for inheritance, unmapped foreign keys, max length, db data type, ... this could go on for a while.