How to define a constraint on class type if It has custom attribute? - c#-4.0

there is any way to force a class to implement an interface , if It has an specific custom attribute?
I want to have a compile time error , if the class with specific attribute does not implement an specific interface.
[myAttrib]
public MyClass:IMyInterface
{
}
If myClass is not typeof(IMyInterface) , I will get an error in compile time.
thanks,

In case of properties, You could create an abstract class inheriting the interface and gets your final class drive from that abstract class.
Have a look at
public interface Test
{
string Name { get; set; }
}
public abstract class Test1 : Test
{
public abstract string Name { get; set; }
}
public class Test2 : Test1
{
}
For custom attribute you could do
public class Alias : System.Attribute
{
string[] _types;
public Alias(params string[] types)
{
this.Types = types;
}
public Alias()
{
this.Types = null;
}
public string[] Types
{
get { return _types; }
set { _types = value; }
}
}
public interface Test
{
Alias Attrib{ get;}
}
public abstract class Test1 : Test
{
public abstract Alias Attrib { get; }
}
public class Test2 : Test1
{
}
Hope I answer your question.

Related

Automapper Base type, dervied type DTO Mapping

I have the following classes:
public class Entity
{
}
public class Company : Entity
{
}
public class Person : Entity
{
}
public class SomeOther
{
public Entity A { get; set; }
}
And the following DTOs:
public class EntityDTO
{
}
public class SomeOtherDTO
{
public EntityDTO A { get; set; }
}
And the following Mappings:
CreateMap<Person, EntityDTO>();
CreateMap<Company, EntityDTO>();
Is there any way of doing CreateMap<Entity, EntityDTO>() and tell Automapper to use the relevant mapping based on the derived type?

Nhibernate confused by class inheritance and returns mixed results

I have a class with a few properties and some methods
public class Content
{
public int Id { get; set; }
public string Application { get; set; }
public string Property1 { get; set; }
public string Property2 { get; set; }
public override bool Equals(object obj) {...}
public override int GetHashCode() {...}
}
With this Fluent NHibernate mapping:
public class ContentMapping : ClassMap<Content>
{
public ContentMapping()
{
Table("vw_all_contents");
CompositeId()
.KeyProperty(x => x.Id, "id")
.KeyProperty(x => x.Application, "application");
Map(x => x.Property1, "property1");
Map(x => x.Property2, "property2");
}
}
Up to here everything works fine.
I now want to populate the same object but with a table a federated table that connects to another database.
So I have:
public class ContentOnProductionDatabase : Content { }
With a mapping:
public class ContenOnProductionDatabasetMapping : ClassMap<ContentOnProductionDatabase>
{
public ContentOnProductionDatabaseMapping()
{
Table("vw_federated_all_contents");
CompositeId()
.KeyProperty(x => x.Id, "id")
.KeyProperty(x => x.Application, "application");
Map(x => x.Property1, "property1");
Map(x => x.Property2, "property2");
}
}
And here is where NHibernate gets really confused and the queries return mixed results from both databases.
The problem goes away if my ContentOnProductionDatabase does not extend Content but instead is a duplicate class like this:
public class ContentOnProductionDatabaseMapping
{
public int Id { get; set; }
public string Application { get; set; }
public string Property1 { get; set; }
public string Property2 { get; set; }
public override bool Equals(object obj) {...}
public override int GetHashCode() {...}
}
So now everything is fine but I don't like the fact that there is so much code duplication and it seems to me there must be some sort of Mapping configuration out there to force NHibernate to ignore the inheritance and differentiate the two, especially since they map to different databases.
The repository framework is an inbuilt one handles the session and the queries.
public class ContentRepository : NHibernateRepositoryBase, IContentRepository
{
public ContentRepository(INHibernateContext context, ISettingsManager settingsManager): base(context){ }
public Content ReadContent(int id, string application)
{
using (ISessionContainer container = Context.GetSessionContainer())
{
return
container.AsQueryable<Content>()
.FirstOrDefault(c => c.Id == id && c.Application == application);
// All queries using <Content> return the correct results
}
}
public ContentOnProductionDataBase ReadFederatedContent(int id, string application)
{
using (ISessionContainer container = Context.GetSessionContainer())
{
return
container.AsQueryable<ContentOnProductionDataBase>()
.FirstOrDefault(c => c.Id == id && c.Application == application);
// All queries using <ContentOnProductionDataBase> return the combined results of <Content> and <ContentOnProductionDataBase>
}
}
}
Internally the container.AsQueryable works by invoking this:
public IQueryable<TEntity> AsQueryable<TEntity>() where TEntity : class
{
return LinqExtensionMethods.Query<TEntity>(this.Session);
}
Any ideas how to get rid of the code duplication?
To define the class mapping and the properties only once, you have to define a base class and define the mapping with UseUnionSubclassForInheritanceMapping which will allow you to use independent tables per entity which is derived from that base class.
You don't have to but you should declare your base class as abstract, because it will not have a database representation. So persisting the base class will fail! Meaning, you don't want anyone to use it as an entity, instead use your derived classes...
To do so, create one base, and 2 derived classes which should be stored in one table per class.
public abstract class ContentBase
{
public virtual int Id { get; set; }
public virtual string Application { get; set; }
public virtual string Property1 { get; set; }
public virtual string Property2 { get; set; }
public override bool Equals(object obj)
{
[..]
}
public override int GetHashCode()
{
[..]
}
}
public class Content : ContentBase
{
}
public class ContentOnProductionDatabaset : ContentBase
{
}
The mapping of the base class must call UseUnionSubclassForInheritanceMapping, otherwise nHibernate would combine the classes.
public class ContentBaseMapping : ClassMap<ContentBase>
{
public ContentBaseMapping()
{
UseUnionSubclassForInheritanceMapping();
CompositeId()
.KeyProperty(x => x.Id, "id")
.KeyProperty(x => x.Application, "application");
Map(x => x.Property1, "property1");
Map(x => x.Property2, "property2");
}
}
The subclass mappings just have to define that the base is abstract.
Here you can also define each table name the entity should use.
public class ContentMapping : SubclassMap<Content>
{
public ContentMapping()
{
Table("vw_all_contents");
Abstract();
}
}
public class ContentOnProductionDatabaseMapping : SubclassMap<ContentOnProductionDatabaset>
{
public ContentOnProductionDatabaseMapping()
{
Table("vw_federated_all_contents");
Abstract();
}
}

ServiceStack QueryBase class for Paging + Sorting, but Validation not fired

I've created a QueryBase class in order to support Paging and Sorting when needed.
public class QueryBase
{
public string Sort { get; set; }
public int PageNumber { get; set; }
public int PageSize { get; set; }
}
If a class supports these features, it'll simply extend it like this:
public class Cars: QueryBase, IReturn<CarsResponse>
{
}
public class CarsResponse : IHasResponseStatus
{
public List<Car> Cars { get; set; }
public ResponseStatus ResponseStatus { get; set; }
}
Then in order to fill QueryBase from querystring I've created a RequestFilterAttribute that can be used when needed:
public class QueryRequestFilterAttribute : Attribute, IHasRequestFilter
{
#region IHasRequestFilter Members
public IHasRequestFilter Copy()
{
return this;
}
public int Priority
{
get { return -100; }
}
public void RequestFilter(IHttpRequest req, IHttpResponse res, object requestDto)
{
var request = requestDto as QueryBase;
if (request == null) { return; }
request.PageNumber = req.QueryString["pageNumber"].IsEmpty() ? 1 : int.Parse(req.QueryString["pageNumber"]);
request.PageSize = req.QueryString["pageSize"].IsEmpty() ? 15 : int.Parse(req.QueryString["pageSize"]);
request.Sort = req.QueryString["sort"].IsNullOrEmpty() ? "id" : req.QueryString["sort"];
}
#endregion
}
Everything is working properly, but my goal now is to enable Validation in order to define some basic rules like maxpagesize or minpagenumber.
A very basic implementation is:
public class QueryBaseValidator : AbstractValidator<QueryBase>
{
public QueryBaseValidator()
{
RuleFor(query => query.PageSize).LessThanOrEqualTo(100).GreaterThan(0);
}
}
In this way validator filter is not able to find the validator above in its cache, because it searches for Cars instead of QueryBase (line 11 ValidationFilter.cs):
ValidatorCache.GetValidator(req, requestDto.GetType());
What is the best solution for this problem in order to avoid writing same validation logic in each subclass?
I found a solution but I don't know if it's the best one: using a validator for each class implementing QueryBase.
QueryBaseValidator modified as follows:
public class QueryBaseValidator<T> : AbstractValidator<T> where T : QueryBase
{
public QueryBaseValidator()
{
RuleFor(query => query.PageSize).LessThanOrEqualTo(100).GreaterThan(0);
}
}
Additional validator created for subclass Cars
public class CarsValidator : QueryBaseValidator<Cars>
{
}
In this way everything works and I've now a basic implementation of generic paging, sorting and very soon query with ServiceStack.

Contra variance with interfaces

I have an interface iExportColumn and a class ExportColumn implementing the interfce. ExportColumnCollection class should be generic for all the classes that implements IExportColumn interface.
public interface IExportColumn
{
string Header { get; set; }
string ColumnName { get; set; }
}
public class ExportColumn : IExportColumn
{
public ExportColumn(){}
public string Header { get; set; }
public string ColumnName { get; set; }
}
public class ExportColumnCollection<T> where T: IExportColumn
{
private List<T> cols;
public ExportColumnCollection (List<T> c)
{
cols = c;
}
public T Columninfo (string colname)
{
}
.....
}
I am getting run time error saying could not load type ExportColumnCollection.
I am looking for something to achieve somthing like
List<IExportColumn> = new List<ExportColumn>();
I have two classes implementing the interfaces IExportColumn and I need to hold a GenericCollection to handle List
The proper usage for your class would be:
List<IExportColumn> list= new List<IExportColumn>();
// you may add to the collection any class which implements IExportColumn
list.Add(new ExportColumn1() { ColumnName = "Id" });
list.Add(new ExportColumn2() { ColumnName = "Value" });
ExportColumnCollection<IExportColumn> collection = new
ExportColumnCollection<IExportColumn>(list);
var colInfo = collection.ColumnInfo("Id");

Inheritance Generic Invariance C#4

I've been searching why this generic contruction doesn't compile
I get:
Cannot implicitly convert type 'WpfApplication1.CowDao' to 'WpfApplication1.Dao'
public abstract class Animal { }
public class Dog : Animal { }
public class Cow : Animal { }
public abstract class Dao<T> where T : Animal
{
public void Insert(T t);
}
public class DogDao : Dao<Dog> { }
public class CowDao : Dao<Cow> { }
public class Main
{
public Main()
{
Dao<Animal> dao = null;
if (true) dao = new DogDao();
else dao = new CowDao();
}
}
I just want to get to my goal --> making a 'neutral' instance
I think that my construction has to change, but i don't know how
I'm using .NET Framework 4
Thanks
Generics from a derived does not inherit from Generic from a base class so you may not cast one to another. Instead, write an extension method ToGenericParent that converts like that:
public static Generic<Parent> ToGenericParent(this Generic<Derived> derived)
{
return new Generic<Parent>() { Value = derived.Value };
}
Change your Inheritance for your Dao layers as
public class DogDao : Dao<Animal> { }
public class CowDao : Dao<Animal> { }
Edit:
public abstract class Dao<T> where T : Animal
{
public virtual void Insert(T t)
{
}
protected void ExecuteQuery(string quer)
{
}
}
public class DogDao : Dao<Dog>
{
public override void Insert(Dog t)
{
string insert = "INSERT INTO DOG ...";
base.ExecuteQuery(insert);
}
}
public class CowDao : Dao<Cow>
{
public override void Insert(Cow t)
{
string insert = "INSERT INTO COW ...";
base.ExecuteQuery(insert);
}
}

Resources