NHibernate mapping domain "extension properties"? - c#

I would like to "extend" my domain classes without having to add data to the domain classes themselves. Consider I have the following class:
public class Person
{
public virtual int Id { get; private set; }
public virtual string Name { get; set; }
}
And I have the following table in the database:
tblPersons
---------------
Id integer
Name varchar(50)
CreatedBy varchar(50)
CreatedDate datetime
So I don't want to add "CreatedBy" and "CreatedDate" to my domain class, because this has nothing to do with the actual domain itself...
Would it be possible to get this data whenever I load an entity? I would like to use it like this:
Person person = session.Load<Person>(1);
person.CreatedBy(); <-- CreatedBy is an Extension function
person.CreatedDate(); <-- CreatedDate is an Extension function
Can anyone point me in which direction to go in order to implement this?
I have thought about the following possibilities:
Implement a custom ProxyFactory, where I inject a custom "interface" such as IUpdateable, howver it seems like NHibernate doesn't create the proxies consistently, sometimes it loads a my "proxy class" class, and sometimes it loads the "normal class":
Person person = session.Load<Person>(2); //this will load my Proxy class of Person just fine
Address address = person.Address; //Somehow this doesn't load a Proxy for Address, but instead loads it normally - seems like it's evaluating "ImmediateLoad", which doesn't load proxies, due to lazy loading... not sure how to make this behave as I want.
Using a custom PropertyAccessor. I have read something about this - but it seems I must actually map this to a property that EXITS on the domain class... so that wouldn't work, right?
Just as NHibernate "injects" code to the runtime when creating the Proxy classes - perhaps I could do the same but inject the "interface" to the original Person class instead?

You can easily do this using a base class or a component mapping. I would not use extension methods for this purpose. I use a base class:
public abstract class Auditable : IAuditable
{
public virtual string CreatedBy { get; set; }
public virtual DateTime CreatedDate { get; set; }
}
public class Person : Auditable {}
Fluent mapping:
public class AuditableClassMap<T> : ClassMap<T> where T: IAuditable
{
public AuditableClassMap()
{
Map(x => x.CreatedBy);
Map(x => x.CreatedDate);
}
}
public class PersonMap : AuditableClassMap<Person> {}
If you are adamant about keeping audit properties out of your classes you could map the audit properties as a component.

Here is one idea. I've never implemented this, so take it with a grain of salt until you've tested it.
Create a different class that encapsulates the audit data for Person -- PersonCreation or something.
Give it an identifier, a created date, and created-by property, and a property for the Person id (I see no need actually reference the Person, unless the identifier is non-public, in which case you may want a WeakReference so you don't keep every Person instance in memory for the life of the application).
You'll need to create a mapping for NHibernate to get PersonCreation objects from the Person table.
From here, you could simply have the extension methods fetch data when called. This may or may not be reasonable depending on your usage. You'll have to create a new session every time or synchronize a static session.
Or…
In the static class that contains your CreatedBy() and CreatedDate() extension methods, create a static IDictionary<int, PersonCreation> to hold the details for each Person. Since creation data is presumably immutable, we don't really have to worry about this becoming stale.
You'll want to batch queries for the PersonCreation with your Person queries. For example, you could do something like:
var creation = session.CreateCriteria<PersonCreation>()
.Add(Restrictions.Eq("PersonId", 1))
.Future<PersonCreation>();
var person = session.CreateCriteria<Person>()
.Add(Restrictions.IdEq(1))
.UniqueResult<Person>();
By calling Future<T>(), you're telling NHibernate not to execute that query until the session is already going to database anyway.
Once you get results, you can take the first creation result and add it to the dictionary (so the extension methods have access to it), and return the person.
When you call person.CreatedDate(), the method can just pull the data from the dictionary using the id of the passed Person paramater, or the Person itself.

Related

Make a data binding between 2 properties in different classes

I have to classes in C# every one contain one proptery so i want to make a data binding between the proprty in the first class and the property in the other one how can i do it. There is an example:
public class FirstClass
{
public string Name { get; set; }
public void BindNameFromRealName()
{
// what can i write here ?
}
}
public class Origine
{
public string RealName { get; set; }
}
You have to have a way to feed the Origine class into the FirstClass. Perhaps a required property for Origine in FirstClass? You can't magically make it know there are other objects in play.
I echo the previous post. Perhaps you want to evaluate your need; what exactly is it you're trying to do. Why do you want to carry data using 2 objects instead of one? If this is like Data Transfer Object <-> Business Object data transfer in scenarios like web service calls, then you might want to check object mapping frameworks like Automapper

Configure EntityFramework 6 to construct navigation properties for me?

I'm using EF6 Code First, I have a sample class
public class Department
{
public Department()
{
Workers = new List<Employee>();
}
public int Id { get; set; }
public virtual List<Employee> Workers { get; set; }
}
Do I really need that horrible constructor there?
I mean, the collection will not construct itself by magic, but I write code in such a way that all EF entities are always proxies (using Create() on DbSets when I need a new object). So I first expected for those "lazy" properties just to initialize themselves. After all, that's what proxies are for, I do these kind of things with Castle.Proxy, for example. But it seems that this functionality is not included in EF, or am I wrong?
I know I can write my own monstrous-looking property for lazy initialization of this collection, and then copy it everywhere I go, but I might as well be stuck with putting it all in the constructor. My goal is for my POCOs to look Plain.
Maybe there is a way to write some custom interceptor that will first initialize the collection if it is null?

Alternative to static nested classes in C# for grouping a classes public methods?

I am attempting to create an internet accessible business object database layer.
I would like to call the database accessor methods like the following:
_databaseHander.Employee.SelectBetweenDates(date1, date2);
_databaseHandler.PayDetails.SelectAll();
_databaseHandler.BusinessArea.InsertAll(businessAreaData);
called via HTTP this would get translated to the following:
www.website.com/DatabaseObject/Employee/SelectBetweenDates/Date1=yyyyMMdd&Date2=yyyyMMdd
www.website.com/DatabaseObject/BusinessArea/InsertAll (will be sent as a post)
I am unsure how this would be done. I would expect it would be something like the following:
public class DatabaseHandler
{
private DatabaseContext _context;
public DatabaseHandler(DatabaseContext context)
{
_context = context;
}
public static class Employee
{
public static IEnumerable<EmployeeData> SelectBetweenDates(DateTime date1, DateTime date2)
{
return _context.Select(x=>x.FromDate <=date1 && x.ToDate>=date2);
}
}
}
This seems like a misuse of 'static'... And am not even sure if it's possible to code this way. Does anyone have any ideas on how I could proceed?
The reasons I am attempting to split up the method calls is so that the auto-complete is useful ie. typing _databaseHandler. will not return 4 or 5 methods per database object.
I would also like to split the class up into partial classes for better readability to avoid a 10,000 line class.
Create a separate class, which can be non-nested - then have a property in DatabaseHandler which returns an instance.
I don't think this should actually be called Employee however, as it clearly doesn't represent an individual employee. It's more of an EmployeeCollection. To be honest, you could potentially just return an IQueryable<EmployeeData> (I'm assuming this is LINQ-based), and then add extension methods in a separate static class to add collection-specific queries.
Employee theEmployee = new Employee();
Would give you an Employee object to work with.
With this you could change the values of the Employee class from DataBaseHandler

asp.net mvc4 EF5 Singleton?

I have a project going on and I'd like to have one unique instance of a class.
I have a 'JobOffer' class, which has a property of type 'OfferStatus' (which is abstract and implements a state pattern). I have 'StateAvailable' and 'StateUnavailable' (or 'open' and 'closed' if you wish).
The 'JobOffer' objects have to be stored in the db.
I'd like to have just one 'StateAvailable' and one 'StateUnavailable', so when I create a new JobOffer I reference to 'StateAvailable' or 'StateUnavailable', and then I could list all the jobOffers which are Open (available) and all that are Closed (unavailable).
I know that I could do this by adding the states in the db in the seed method, and never instantiate a new state.
But I was wondering if it is possible to do a singleton or something to avoid that somebody (I mean controller, model or anything) can create new instances of that class.
public class JobOffer {
public int JobOfferId {get;set;}
public OfferState State {get;set;
public virtual ICollection<Person> People {get;set;}
//And some methods here, which depends on the state
//ie, this.State.myMethod();
My first thought was to use a boolean. Then you said you have to be able to expand to have more states, so I thought of an enum. Then you said you have this requirement to use a class, so... here's a little something I use when I want an enum with more smarts. You could call it a sort of "enumerating class", I suppose. So, your OfferState class looks like this:
public sealed class OfferState
{
public bool CanChangeState { get; set; }
//whatever properties you need
public static OfferState Available = new OfferState(true);
public static OfferState Unavailable = new OfferState(true);
public static OfferState Closed = new OfferState(false);
//whatever states you need
public OfferState(bool canChange)
{
CanChangeState = canChange;
}
}
This acts kind of like an enum, but it has properties like a class. So in your logic, you can check state:
if (jobOffer.State == OfferState.Available)
{
//stuff
}
You can also get properties off it, so you can use it to get information about the state:
jobOffer.ExpiryDate = jobOffer.CreationDate.Add(OfferState.Available.MaxDuration);
And of course, the static nature of the various states will ensure that there's only ever one instance of each.

Class extending - best practice/best solution

First thing to note - I KNOW DELEGATION AND DECORATOR PATTERNS!
Second - I am using C# .NET 4.0, so if you come up with a solution that is specific for it, that's fine. But if solution will work for any OOP language and platform, that would be great.
And here the question goes...
I have a partial class (lets name it Class1), which I cannot modify. Thus, I can just extend it or/and inherit from it. This class provides a perfect data model for me, the only thing I need is to add some attributes to its properties (for validation, defining label text value in MVC etc - for now, I do not need answers like 'you can do what you need without attributes', that's not the matter of my question).
It is not a problem to use another class as a data model, so I can, say, create Class2 : Class1 and use Class2 as a model. Properties that need attributes would be defined as public new <type> <propertyname>. This will limit me to rewriting only the properties that need attributes, leaving all other untouched.
The smaller problem is that I do not what to redefine getters and setters for the properties, as all they gonna contain is return base.<propertyname> and base.<propertyname> = value, and if there are lots of such properties, this means lots of "stupid" coding. Is there a way to avoid this?
The bigger problem is that I have to parametrize my Class2 with Class1 instance and make something like class2.<propertyname> = class1.<propertyname> for each single property I have - too much of "stupid" coding. I can avoid it using reflection - find all properties with public getters and setters in Class1 and call prop.SetValue(child, prop.GetValue(parent, null), null); in the loop. This provides a generic function for simple cases, which is quite fine, as I mostly have simple models - lots of properties with public getters and setters without body and another logic. But I want more generic solution, and I do not like reflection. Any ideas?
Here goes the full code of the extension method that creates Class2 basing on Class1
public static Child ToExtendedChild<Parent, Child>(this Parent parent)
where Child : Parent, new()
{
Child child = new Child();
var props = typeof(Parent).GetProperties().Where(p => p.GetAccessors().Count() >= 2);
foreach (var prop in props)
{
prop.SetValue(child, prop.GetValue(parent, null), null);
}
return child;
}
(by the way, this method may not ideally implement my solution, so any corrections would also be appreciated)
Thanks in advance!
The smaller problem doesn't seem to be much of a problem. Maybe I'm misunderstanding the question, but assuming you're simply deriving a subclass, there should be no reason to redefine either the properties or their associated getters/setters.
The bigger problem might be resolved using something a little simpler. Using reflection for a lot of your object initialization seems a little expensive. If you're dealing with a class that is primarily a big bag or properties, maybe you should as if you need access to all of those properties in any given situation. You mention MVC and validation, is the entire model being used in the controller method you're validation is taking place in? If not, why not look at using a viewmodel that only exposes those pieces you need in that method?
Your reflection initializer is interesting, but if you're going to be doing a lot of this then you might consider investing a little time with Automapper. Otherwise maybe consider moving away from a generic solution to something that just tackles the problem at hand, i.e. mapping properties from an instance of an object to another instance of a derived object. Maybe you can create a copy constructor in the parent class and use that in your derived class?
public class Foo {
public string PropOne { get; set; }
public string PropTwo { get; set; }
public Foo(string propOne, string propTwo) {
PropOne = propOne;
PropTwo = propTwo;
}
public Foo(Foo foo) {
PropOne = foo.PropOne;
PropTwo = foo.PropTwo;
}
}
public class Pho : Foo {
// if you have additional properties then handle them here
// and let the base class take care of the rest.
public string PropThree { get; set; }
public Pho(string propOne, string propTwo, string propThree)
: base(propOne, propTwo) {
PropThree = propThree;
}
public Pho(Pho pho) : base(pho) {
PropThree = pho.PropThree;
}
// otherwise you can just rely on a copy constructor
// to handle the initialization.
public Pho(Foo foo) : base(foo) {}
}
I assume the partial class is generated code, it makes the most sense given your scenario.
I know of one way to do this, but depending on how the attribute gets crawled, it may not work.
// Generated Code
public partial Class1
{
public string Foo { get { ... } }
}
// Your Code
public interface IClass1
{
[MyAttribute]
public string Foo { get; }
}
public partial Class1 : IClass1
{
}
If someone were to look at attributes by using GetCustomAttributes with inheritance, then I think they would get this attribute.
As an aside, whenever I see generated code that doesn't have virtual properties it makes me cry a little bit inside.
To address your bigger question, why don't you just make Class2 a wrapper for Class1. Instead of copying all of the properties you can just give Class2 an instance of Class1 in the constructor, store it locally and make all of your properties pass-throughs. It means some hand coding, but if you're building a Class2 by hand anyway and want to decorate it with a bunch of attributes, well, you're hand coding Class2 anyway.

Categories