Entities used by ORM in combination with CodeContracts - ensure invariants - c#

I am currently in the process of adding CodeContracts to my existing code base.
One thing that proves difficult is the usage of entities that are hydrated by NHibernate.
Assume this simple class:
public class Post
{
private Blog _blog;
[Obsolete("Required by NHibernate")]
protected Post() { }
public Post(Blog blog)
{
Contract.Requires(blog != null);
_blog = blog;
}
public Blog Blog
{
get
{
Contract.Ensures(Contract.Result<Blog>() != null);
return _blog;
}
set
{
Contract.Requires(value != null);
_blog = value;
}
}
[ContractInvariantMethod]
private void Invariants()
{
Contract.Invariant(_blog != null);
}
}
This class tries to protect the invariant _blog != null. However, it currently fails, because I easily could create an instance of Post by deriving from it and using the protected constructor. In that case _blog would be null.
I am trying to change my code-base in a way that the invariants are indeed protected.
The protected constructor is at first sight needed by NHibernate to be able to create new instances, but there is a way around this requirement.
That approach basically uses FormatterServices.GetUninitializedObject. The important point is, that this method doesn't run any constructors.
I could use this approach and it would allow me to get rid of the protected constructor. The static checker of CodeContracts would now be happy and not report any more violations, but as soon as NHibernate tries to hydrate such entities it will generate "invariant failed" exceptions, because it tries to set one property after the other and every property setter executes code that verifies the invariants.
So, to make all this work, I will have to ensure that the entities are instantiated via their public constructor.
But how would I do this?

Daniel, if I'm not mistaken (it's been a while since I worked with NH) you can have a private constructor and he still should be fine creating your object.
Aside from that, why do you need to be a 100% sure? Is it a requirement in some way or you are just trying to covering all the bases?
I ask that because depending on the requirement we could come with another way of achieving it.
What you COULD do right now to provide that extra protection is wire up an IInterceptor class to make sure that after the load your class is still valid.
I guess that the bottom line is if someone want's to mess up with your domain and classes they WILL do it no matter what you do. The effort to prevent all that stuff doesn't pay off in most cases.
Edit after clarification
If you use your objects to write to the database and you contracts are working you can safely assume that the data will be written correctly and therefore loaded correctly if no one tampers with the database.
If you do change the database manually you should either stop doing it and use your domain to do that (that's where the validation logic is) or test the database changing process.
Still, if you really need that you can still hook up a IInterceptor that will validate your entity after the load, but I don't think you fix a water flooding coming from the street by making sure your house pipe is fine.

Based on the discussion with tucaz, I came up with the following, in its core rather simple solution:
The heart of this solution is the class NHibernateActivator. It has two important purposes:
Create an instance of an object without invoking its constructors. It uses FormatterServices.GetUninitializedObject for this.
Prevent the triggering of "invariant failed" exceptions while NHibernate hydrates the instance. This is a two-step task: Disable invariant checking before NHibernate starts hydrating and re-enable invariant checking after NHibernate is done.
The first part can be performed directly after the instance has been created.
The second part is using the interface IPostLoadEventListener.
The class itself is pretty simple:
public class NHibernateActivator : INHibernateActivator, IPostLoadEventListener
{
public bool CanInstantiate(Type type)
{
return !type.IsAbstract && !type.IsInterface &&
!type.IsGenericTypeDefinition && !type.IsSealed;
}
public object Instantiate(Type type)
{
var instance = FormatterServices.GetUninitializedObject(type);
instance.DisableInvariantEvaluation();
return instance;
}
public void OnPostLoad(PostLoadEvent #event)
{
if (#event != null && #event.Entity != null)
#event.Entity.EnableInvariantEvaluation(true);
}
}
DisableInvariantEvaluation and EnableInvariantEvaluation are currently extension methods that use reflection to set a protected field. This field prevents invariants from being checked. Furthermore EnableInvariantEvaluation will execute the method that checks the invariants if it gets passed true:
public static class CodeContractsExtensions
{
public static void DisableInvariantEvaluation(this object entity)
{
var evaluatingInvariantField = entity.GetType()
.GetField(
"$evaluatingInvariant$",
BindingFlags.NonPublic |
BindingFlags.Instance);
if (evaluatingInvariantField == null)
return;
evaluatingInvariantField.SetValue(entity, true);
}
public static void EnableInvariantEvaluation(this object entity,
bool evaluateNow)
{
var evaluatingInvariantField = entity.GetType()
.GetField(
"$evaluatingInvariant$",
BindingFlags.NonPublic |
BindingFlags.Instance);
if (evaluatingInvariantField == null)
return;
evaluatingInvariantField.SetValue(entity, false);
if (!evaluateNow)
return;
var invariantMethod = entity.GetType()
.GetMethod("$InvariantMethod$",
BindingFlags.NonPublic |
BindingFlags.Instance);
if (invariantMethod == null)
return;
invariantMethod.Invoke(entity, new object[0]);
}
}
The rest is NHibernate plumbing:
We need to implement an interceptor that uses our activator.
We need to implement an reflection optimizer that returns our implementation of IInstantiationOptimizer. This implementation in turn again uses our activator.
We need to implement a proxy factory that uses our activator.
We need to implement IProxyFactoryFactory to return our custom proxy factory.
We need to create a custom proxy validator that doesn't care whether the type has a default constructor.
We need to implement a bytecode provider that returns our reflection optimizer and proxy-factory factory.
NHibernateActivator needs to be registered as a listener using config.AppendListeners(ListenerType.PostLoad, ...); in ExposeConfiguration of Fluent NHibernate.
Our custom bytecode provider needs to be registered using Environment.BytecodeProvider.
Our custom interceptor needs to be registered using config.Interceptor = ...;.
I will update this answer when I had the chance to create a coherent package out of all this and put it on github.
Furthermore, I want to get rid of the reflection and create a proxy type instead that can directly access the protected CodeContract members.
For reference, the following blog posts where helpful in implementing the several NHibernate interfaces:
http://weblogs.asp.net/ricardoperes/archive/2012/06/19/implementing-an-interceptor-using-nhibernate-s-built-in-dynamic-proxy-generator.aspx
http://kozmic.net/2011/03/20/working-with-nhibernate-without-default-constructors/
Unfortunately, this currently fails for entities with composite keys, because the reflection optimizer is not used for them. This is actually a bug in NHibernate and I reported it here.

Related

Use ExpandoObject to create a 'fake' implementation of an interface - adding methods dynamically

A brainteaser for you!
I am developing a modular system, in such a way that module A could need module B and module B could also need module A. But if module B is disabled, it will simply not execute that code and do nothing / return null.
A little bit more into perspective:
Let's say InvoiceBusinessLogic is within module "Core". We also have a "Ecommerce" module which has a OrderBusinessLogic. The InvoiceBusinessLogic could then look like this:
public class InvoiceBusinessLogic : IInvoiceBusinessLogic
{
private readonly IOrderBusinessLogic _orderBusinessLogic;
public InvoiceBusinessLogic(IOrderBusinessLogic orderBusinessLogic)
{
_orderBusinessLogic = orderBusinessLogic;
}
public void UpdateInvoicePaymentStatus(InvoiceModel invoice)
{
_orderBusinessLogic.UpdateOrderStatus(invoice.OrderId);
}
}
So what I want is: When the module "Ecommerce" is enabled, it would actually do something at the OrderBusinessLogic. When not, it would simply not do anything. In this example it returns nothing so it can simply do nothing, in other examples where something would be returned, it would return null.
Notes:
As you can probably tell, I am using Dependency Injection, it is a ASP.NET Core application so the IServiceCollection takes care of defining the implementations.
Simply not defining the implementation for IOrderBusinessLogic will cause a runtime issue, logically.
From a lot of research done, I do not want to make calls to the container within my domain / logic of the app. Don't call the DI Container, it'll call you
These kind of interactions between modules are kept to a minimum, preferably done within the controller, but sometimes you cannot get around it (and also in the controller I would then need a way to inject them and use them or not).
So there are 3 options that I figured out so far:
I never make calls from module "Core" to module "Ecommerce", in theory this sounds the best way, but in practice it's more complicated for advanced scenarios. Not an option
I could create a lot of fake implementations, depending on the configuration decide on which one to implement. But that would of course result in double code and I would constantly have to update the fake class when a new method is introduced. So not perfectly.
I can build up a fake implementation by using reflection and ExpandoObject, and just do nothing or return null when the particular method is called.
And the last option is what I am now after:
private static void SetupEcommerceLogic(IServiceCollection services, bool enabled)
{
if (enabled)
{
services.AddTransient<IOrderBusinessLogic, OrderBusinessLogic>();
return;
}
dynamic expendo = new ExpandoObject();
IOrderBusinessLogic fakeBusinessLogic = Impromptu.ActLike(expendo);
services.AddTransient<IOrderBusinessLogic>(x => fakeBusinessLogic);
}
By using Impromptu Interface, I am able to successfully create a fake implementation. But what I now need to solve is that the dynamic object also contains all the methods (mostly properties not needed), but those ones are easy to add. So currently I am able to run the code and get up until the point it will call the OrderBusinessLogic, then it will, logically, throw an exception that the method does not exist.
By using reflection, I can iterate over all the methods within the interface, but how do I add them to the dynamic object?
dynamic expendo = new ExpandoObject();
var dictionary = (IDictionary<string, object>)expendo;
var methods = typeof(IOrderBusinessLogic).GetMethods(BindingFlags.Public);
foreach (MethodInfo method in methods)
{
var parameters = method.GetParameters();
//insert magic here
}
Note: For now directly calling typeof(IOrderBusinessLogic), but later I would iterate over all the interfaces within a certain assembly.
Impromptu has an example as follows:
expando.Meth1 = Return<bool>.Arguments<int>(it => it > 5);
But of course I want this to be dynamic so how do I dynamically insert the return type and the parameters.
I do understand that a interface acts like a contract, and that contract should be followed, I also understand that this is an anti-pattern, but extensive research and negotiations have been done prior to reaching this point, for the result system we want, we think this is the best option, just a little missing piece :).
I have looked at this question, I am not really planning on leaving .dll's out, because most likely I would not be able to have any form of IOrderBusinessLogic usable within InvoiceBusinessLogic.
I have looked at this question, but I did not really understand how TypeBuilder could be used in my scenario
I have also looked into Mocking the interfaces, but mostly you would then need to define the 'mocking implementation' for each method that you want to change, correct me if I am wrong.
Even tough the third approach (with ExpandoObject) looks like a holy grail, I foster you to not follow this path for the following reasons:
What guarantees you that this fancy logic will be error-free now and at every time in the future ? (think: in 1 year you add a property in IOrderBusinessLogic)
What are the consequences if not ? Maybe an unexpected message will pop to the user or cause some strange "a priori unrelated" behavior
I would definitely go down the second option (fake implementation, also called Null-Object) even though, yes it will require to write some boilerplate code but ey this would offer you a compile-time guarantee that nothing unexpected will happen at rutime !
So my advice would be to do something like this:
private static void SetupEcommerceLogic(IServiceCollection services, bool enabled)
{
if (enabled)
{
services.AddTransient<IOrderBusinessLogic, OrderBusinessLogic>();
}
else
{
services.AddTransient<IOrderBusinessLogic, EmptyOrderBusinessLogic>();
}
}
For as long as there is no other answer for the solution I am looking for, I came up with the following extension:
using ImpromptuInterface.Build;
public static TInterface IsModuleEnabled<TInterface>(this TInterface obj) where TInterface : class
{
if (obj is ActLikeProxy)
{
return default(TInterface);//returns null
}
return obj;
}
And then use it like:
public void UpdateInvoicePaymentStatus(InvoiceModel invoice)
{
_orderBusinessLogic.IsModuleEnabled()?.UpdateOrderStatus(invoice.OrderId);
//just example stuff
int? orderId = _orderBusinessLogic.IsModuleEnabled()?.GetOrderIdForInvoiceId(invoice.InvoiceId);
}
And actually it has the advantage that it is clear (in the code) that the return type can be null or the method won't be called when the module is disabled. The only thing that should be documented carefully, or in another way enforced, that is has to be clear which classes do not belong to the current module. The only thing I could think of right now is by not including the using automatically, but use the full namespace or add summaries to the included _orderBusinessLogic, so when someone is using it, it is clear this belongs to another module, and a null check should be performed.
For those that are interested, here is the code to correctly add all fake implementations:
private static void SetupEcommerceLogic(IServiceCollection services, bool enabled)
{
if (enabled)
{
services.AddTransient<IOrderBusinessLogic, OrderBusinessLogic>();
return;
}
//just pick one interface in the correct assembly.
var types = Assembly.GetAssembly(typeof(IOrderBusinessLogic)).GetExportedTypes();
AddFakeImplementations(services, types);
}
using ImpromptuInterface;
private static void AddFakeImplementations(IServiceCollection services, Type[] types)
{
//filtering on public interfaces and my folder structure / naming convention
types = types.Where(x =>
x.IsInterface && x.IsPublic &&
(x.Namespace.Contains("BusinessLogic") || x.Namespace.Contains("Repositories"))).ToArray();
foreach (Type type in types)
{
dynamic expendo = new ExpandoObject();
var fakeImplementation = Impromptu.DynamicActLike(expendo, type);
services.AddTransient(type, x => fakeImplementation);
}
}

Chain of responsibility vs Reflection

Sometime ago I removed a chain of responsibility in a web site that I'am working on.
The chain would call a method to generate a dynamic form for the website. Every object called would either return their form or "pass the ball" to the next object to retrieve the form.
The website has around 300+ classes with this logic, no big deal in terms of performance but I found it horrible to see it and debugging it.
So I decided to remove the chain call and just replaced it with reflection, I know what object I have to call by a unique static "name" (the same name was used in the chain to check if the object has to load the form or "pass the ball") of the class and by foreaching all the objects in a list I'll check that name to be sure to call the correct class/method.
I know that reflection is supposed to be slower in terms of performance but after some tests I can't see any sustantial difference and since the code is much cleaner it's easier to understand and debug.
So my question is:
Is this a correct approach or is there any better pattern to use in a case like this ?
I feel like I use reflection more then I should when I'am coding and I don't know if it is always the better option.
This in 1 class:
foreach (TemplateHandler t in objectList)
{
if (t.GetType().GetProperty("serviceCode") != null)
{
if (t.GetType().GetProperty("serviceCode").GetValue(t).ToString() == serviceCodeToCallFromParam)
{
return t.GetTemplateParam(serviceCodeToCallFromParam/*, ...other params...*/);
}
}
}
over this in 300+ class:
public override List<Form> GetTemplateParam(string serviceCode)
{
if (serviceCode == ClassServiceCode)
{
// long form logic build.
//..
}
else
{
if (successor != null)
form = successor.GetTemplateParam(serviceCode);
}
return form;
}
Reflection solution looks better if I have to choose from those two. Passing ball for 300 times looks meaningless.
But, as you noted, the performance might be the issue. If you already know the class to call for getting work done, why not implement something like Builder or Factory pattern to create an instance of appropriate class and get the work done through.
Even simpler is the switch-case structure. Put and creation code in switch-case and use the resultant object to do work.
Edit 1:
public T CreateTemplate<T>() where T : ITemplate
{
ITemplate template = null;
if(typeof(T) == typeof(Type1Template))
template = new Type1Template(....);
else if(typeof(T) == typeof(Type2Template))
template = new Type2Template(....);
else
throw new TemplateException("Template type is not configured.");
return (T)template;
}
Edit 2
See if something like below helps then:
public T CreateTemplate<T>()
{
ITemplate template = (T)Activator.CreateInstance(typeof(T));
return template;
}

Validate entities when adding to a navigation property

I have an entity with a collection property that looks something like this:
public class MyEntity
{
public virtual ICollection<OtherEntity> Others { get; set; }
}
When I retrieve this entity via the data context or repository, I want to prevent others adding items to this collection through the use of MyEntity.Others.Add(entity). This is because I may want some validation code to be performed before adding my entity to the collection. I'd do this by providing a method on MyEntity like this:
public void AddOther(OtherEntity other)
{
// perform validation code here
this.Others.Add(other);
}
I've tested a few things so far, and what I've eventually arrived at is something like this. I create a private collection on my entity and expose a public ReadOnlyCollection<T> so MyEntity looks like this:
public class MyEntity
{
private readonly ICollection<OtherEntity> _others = new Collection<OtherEntity>();
public virtual IEnumerable<OtherEntity>
{
get
{
return _others.AsEnumerable();
}
}
}
This seems to be what I'm looking for and my unit tests pass fine, but I haven't yet started to do any integration testing so I'm wondering:
Is there a better way to achieve what I'm looking for?
What are the implications I'll face if I decide to go down this route (if feasible)?
Thanks always for any and all help.
Edit 1 I've changed from using a ReadOnlyCollection to IEnumerable and am using return _others.AsEnumerable(); as my getter. Again unit tests pass fine, but I'm unsure of the problems I'll face during integration and EF starts building these collections with related entities.
Edit 2 So, I decided to try out suggestions of creating a derived collection (call it ValidatableCollection) implementing ICollection where my .Add() method would perform validation on the entity provided before adding it to the internal collection. Unfortunately, Entity Framework invokes this method when building the navigation property - so it's not really suitable.
I would create collection class exactly for this purpose:
OtherEntityCollection : Collection<OtherEntity>
{
protected override void InsertItem(int index, OtherEntity item)
{
// do your validation here
base.InsertItem(index, item);
}
// other overrides
}
This will make much more rigid, because there will be no way to bypass this validation. You can check more complex example in documentation.
One thing I'm not sure is how to make EF create this concrete type when it materializes data from database. But it is probably doable as seen here.
Edit:
If you want to keep the validation inside the entity, you could make it generic through custom interface, that the entity would implement and your generic collection, that would call this interface.
As for problems with EF, I think the biggest problem would be that when EF rematerializes the collection, it calls Add for each item. This then calls the validation, even when the item is not "added" as business rule, but as an infrastructure behavior. This might result in weird behavior and bugs.
I suggest returning to ReadOnlyCollection<T>. I've used it in similar scenarios in the past, and I've had no problems.
Additionally, the AsEnumerable() approach will not work, as it only changes the type of the reference, it does not generate a new, independent object, which means that this
MyEntity m = new MyEntity();
Console.WriteLine(m.Others.Count()); //0
(m.Others as Collection<OtherEntity>).Add(new OtherEntity{ID = 1});
Console.WriteLine(m.Others.Count()); //1
will successfully insert in your private collection.
You shouldn't use AsEnumerable() on HashSet, because collection can be easily modified by casting it to ICollection<OtherEntity>
var values = new MyEntity().Entities;
((ICollection<OtherEntity>)values).Add(new OtherEntity());
Try to return copy of a list like
return new ReadOnlyCollection<OtherEntity>(_others.ToList()).AsEnumerable();
this makes sure that users will recieve exception if they will try to modify it. You can expose ReadOnlyCollection as return type enstead of IEnumerable for clarity and convenience of users. In .NET 4.5 a new interface was added IReadOnlyCollection.
You won't have big integration issues except some component depend on List mutation. If users will call ToList or ToArray, they will return a copy
You have two options here:
1) The way you are currently using: expose the collection as a ReadOnlyCollection<OtherEntity> and add methods in the MyEntity class to modify that collection. This is perfectly fine, but take into account that you are adding the validation logic for a collection of OtherEntity in a class that just uses that collection, so if you use collections of OtherEntity elsewhere in the project, you will need probably need to replicate the validation code, and that's a code smell (DRY) :P
2) To solve that, the best way is to create a custom OtherEntityCollection class implementing ICollection<OtherEntity> so you can add the validation logic there. It's really simple because you can create a simple OtherEntityCollection object that contains a List<OtherEntity> instance which really implements the collection operations, so you just need to validate the insertions:.
Edit: If you need custom validation for multiple entities you should create a custom collection which receives some other object that perform that validation. I've modified the example below, but it shouldn't be difficult to create a generic class:
class OtherEntityCollection : ICollection<OtherEntity>
{
OtherEntityCollection(Predicate<OtherEntity> validation)
{
_validator = validator;
}
private List<OtherEntity> _list = new List<OtherEntity>();
private Predicate<OtherEntity> _validator;
public override void Add(OtherEntity entity)
{
// Validation logic
if(_validator(entity))
_list.Add(entity);
}
}
EF can't map property without setter. or even private set { } requires some configuration. keep models as POCO, Plain-Old like DTO
the common approach is to create separated service layer that contain validation logic against your Model before save.
for sample..
public void AddOtherToMyEntity(MyEntity myEntity, OtherEntity otherEntity)
{
if(myService.Validate(otherEntity)
{
myEntity.Others.Add(otherEntity);
}
//else ...
}
ps. You could prevent compiler to do somethings but not other coders. Just made your code explicitly says "don't modify Entity Collection directly, until it passed validation"
Finally have a suitable working solution, here's what I did. I'll change MyEntity and OtherEntity to something more readable, like Teacher and Student where I want to stop a teacher teaching more students than they can handle.
First, I created an interface for all entities that I intend to validate in this way called IValidatableEntity that looks like this:
public interface IValidatableEntity
{
void Validate();
}
Then I implement this interface on my Student because I'm validating this entity when adding to the collection of Teacher.
public class Student : IValidatableEntity
{
public virtual Teacher Teacher { get; set; }
public void Validate()
{
if (this.Teacher.Students.Count() > this.Teacher.MaxStudents)
{
throw new CustomException("Too many students!");
}
}
}
Now onto how I invoke validate. I override .SaveChanges() on my entity context to get a list of all entities added and for each invoke validate - if it fails I simply set its state to detached to prevent it being added to the collection. Because I'm using exceptions (something I'm still unsure of at this point) as my error messages, I throw them out to preserve the stack trace.
public override int SaveChanges()
{
foreach (var entry in ChangeTracker.Entries())
{
if (entry.State == System.Data.EntityState.Added)
{
if (entry.Entity is IValidatableEntity)
{
try
{
(entry.Entity as IValidatableEntity).Validate();
}
catch
{
entry.State = System.Data.EntityState.Detached;
throw; // preserve the stack trace
}
}
}
}
return base.SaveChanges();
}
This means I keep my validation code nicely tucked away within my entity which will make my life a whole lot easier when mocking my POCOs during unit testing.

Fluent NHibernate ISessionManager or equivilent

I am quite new to the FNH and NH world, so be gentle :P
I have created an application using FNH for data access which works good while not using lazy-loading, however once I enable lazy-loading everything goes pear shaped (as in, no sessions are open when I attempt to access the lazy-loaded properties etc).
The application layout I have created thus-far has a "Database" singleton which has various methods such as Save(), Refer() and List().
When calling Refer() a session is opened, the data is retrieved and the session is disposed; meaning there is no session available when attempting to access a lazy-loaded property from the returned object. Example: Database.Refer("username").Person since Person is lazy-loaded and the session has already closed.
I have read that Castle has a SessionManager that could be used for this very scenario but, either it's the late nights or lack of coffee, I can't seem to work out how to hook up FNH to use this manager as, in the spirit of castle, everything is defined in config files.
Am I missing something, or can this not be done? Are there any other session managers (or even more appropriate conventions) that I should look at?
Thanks for any help on this matter.
I don't think that your particular problem is connected with the SessionManager as you've already mentioned that you are capable of starting a new session and disposing it whenever needed.
From what I can understand of your post is that you are trying to expose an entity to your view (with some lazy-loaded properties) - which is already a bad idea because it leads to nasty LazyInitializationException(s).
You should consider making a distinguishion between your data-model and your domain model. The key concept has been described on this blog:
Ayende # Rahien
http://ayende.com/blog/4054/nhibernate-query-only-properties
If you say that you are writing a very simple 2-tier application then it probably will not harm if you will micro-manage your session in the data-layer (but keep in mind that this is not the best solution).
I would also look into the query that fetches your entity, as it seems to me that your are trying to obtain data that is just a part of your model - in this case Person. This can lead into serious problems like n+1 selects:
What is SELECT N+1?
So in general I think you should focus more on how things are structured in your application instead of searching for a SessionManager as it will not resolve all of your problems.
For any of you who are still looking for answers on this, I will share with you what I have so far.
This is only a very simple overview of the framework that I have decided to use, and is by far not the only solution for this problem.
The basic layout of my code is as follows:
NHibernate Repository
(references my model assembly and the UoW assembly)
Based on the HibernatingRhino's Repository implementation modified to suit my needs. Found here: http://ayende.com/Wiki/Rhino+Commons.ashx
public T Get(Guid Id)
{
return WrapUOW(() =>
{
using (Audit.LockAudit())
return (T)Session.Get(typeof(T), Id);
});
}
public void LoadFullObject(T partial)
{
if (partial == null)
throw new ArgumentNullException("partial");
if (partial.Id == Guid.Empty)
return;
WrapUOW(() =>
{
using (Audit.LockAudit())
{
LazyInitialiser.InitialiseCompletely(partial, Session);
}
});
}
public T SaveOrUpdate(T entity)
{
using (Audit.LockAudit())
{
With.Transaction(() =>
{
Enlist(entity);
Session.SaveOrUpdate(entity);
entity.HasChanged = false;
});
}
return entity;
}
protected void Enlist(T instance)
{
if (instance != null && instance.Id != Guid.Empty && !Session.Contains(instance))
using (Audit.LockAudit())
{
Session.Update(instance);
}
}
References a neat little helper class called 'Lazy Initializer for NHibernate' found here: http://www.codeproject.com/KB/cs/NHibernateLazyInitializer.aspx
This also contains Extension methods for Save, Delete and LoadFullObject
Have broken standards a little in this assembly by also creating a WrapUOW method to help simplify some of my code
protected static T WrapUOW(Func action)
{
IUnitOfWork uow = null;
if (!UnitOfWork.IsStarted)
uow = UnitOfWork.Start();
T result = action();
if (uow != null)
uow.Dispose();
return result;
}
NHibernate Unit of work
(references my model assembly)
Also based on the HibernatingRhino's UoW implementation and modified to suit
View - not important, just requried for MVVM implementation
Binds the values from the ViewModel
Model
Contains my entity classes and hibernate mapping files
ViewModel
Contains two main view base classes, ListPage and MaintenancePage
The ListPage base class just calls the Repository List method based on the object type we are listing. This loads a dehydrated list of entities.
The MaintenancePage takes an entity instance from the ListPage and calls the Repository.LoadFullObject method to rehydrate the entity for use on the screen.
This allows for the use of binding on the screen.
We can also safely call the Repository.SaveOrUpdate method from this page

Unit testing and nhibernate?

I am wondering how to get around this. I am using nhibernate and fluent.
I have a domain class like this
public class User
{
public virtual int UserId {get; private set;}
}
this seems to be the convention when doing nhibernate as it stops people from setting and id as it is auto generated.
Now the problem comes when I am unit testing.
I have all my nhibernate code in a repo that I mock out so I am only testing my service layer. The problem comes when this happens.
User user = repo.GetUser(email);
this should return a user object.
So I want to use moq to do this
repo.Setup(x => x.GetUser(It.IsAny<string>())).Return(/* UserObject here */)
now here is the problem
I need to make that User object and put it in the Return part.
So I would do something like
User user = new User()
{
UserId = 10,
}
But this is where the problem lies I need to set the Id because I actually use it later on to do some linq on some collections(in the service layer as it is not hitting my db so it should not be in my repo) so I need to have it set but I can't set it because it is a private set.
So what should I do? Should I just remove the private or is there some other way?
You can have the fake Repository object return a fake User object:
var stubUser = new Mock<User>();
stubUser.Setup(s => s.UserId).Returns(10);
var stubRepo = new Mock<IUserRepository>();
stubRepo.Setup(s => s.GetUser(It.IsAny<string>())).Return(stubUser);
There are a couple of things to observe here:
Moq can only fake members of concrete classes if they are marked as virtual. This may not be applicable in some scenarios, in which case the only way to fake an object through Moq is having it implement an interface.In this case, however, the solution works nicely because NHibernate already imposes the same requirement on the properties of the User class in order to do lazy loading.
Having fake objects returning other fakes may sometimes lead to over specified unit tests. In these situations, the construction of rich object models made up of stubs and mocks grows to the point where it becomes difficult to determine what exactly is being tested, making the test itself unreadable and hard to maintain. It is a perfectly fine unit testing practice, to be clear, but it must be used consciously.
Related resources:
Over Specification in Tests
Enrico's answer is spot on for unit testing. I offer another solution because this problem crops up in other circumstances too, where you might not want to use Moq. I regularly use this technique in production code where the common usage pattern is for a class member to be read-only, but certain other classes need to modify it. One example might be a status field, which is normally read-only and should only be set by a state machine or business logic class.
Basically you provide access to the private member through a static nested class that contains a method to set the property. An example is worth a thousand words:
public class User {
public int Id { get; private set; }
public static class Reveal {
public static void SetId(User user, int id) {
user.Id = id;
}
}
}
You use it like this:
User user = new User();
User.Reveal.SetId(user, 43);
Of course, this then enables anyone to set the property value almost as easily as if you had provided a public setter. But there are some advantages with this technique:
no Intellisense prompting for the property setter or a SetId() method
programmers must explicitly use weird syntax to set the property with the Reveal class, thereby prompting them that they should probably not be doing this
you can easily perform static analysis on usages of the Reveal class to see what code is bypassing the standard access patterns
If you are only looking to modify a private property for unit testing purposes, and you are able to Moq the object, then I would still recommend Enrico's suggestion; but you might find this technique useful from time to time.
Another alternative if you prefer not to mock your entity classes is to set the private/protected ID using reflection.
Yes, I know that this is usually not looked upon very favourably, and often cited as a sign of poor design somewhere. But in this case, having a protected ID on your NHibernate entities is the standard paradigm, so it seems a quite reasonable solution.
We can try to implement it nicely at least. In my case, 95% of my entities all use a single Guid as the unique identifier, with just a few using an integer. Therefore our entity classes usually implement a very simple HasID interface:
public interface IHasID<T>
{
T ID { get; }
}
In an actual entity class, we might implement it like this:
public class User : IHasID<Guid>
{
Guid ID { get; protected set; }
}
This ID is mapped to NHibernate as a primary key in the usual manner.
To the setting of this in our unit tests, we can use this interface to provide a handy extension method:
public static T WithID<T, K>(this T o, K id) where T : class, IHasID<K>
{
if (o == null) return o;
o.GetType().InvokeMember("ID", BindingFlags.SetProperty | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, o, new object[] { id });
return o;
}
We don't have to have the HasID interface to do this, but it means we can skip a bit of extra code - for example we don't need to check if the ID is actually supported or not.
The extension method also returns the original object, so in usage I usually just chain it onto the end of the constructor:
var testUser = new User("Test User").WithID(new Guid("DC1BA89C-9DB2-48ac-8CE2-E61360970DF7"));
Or actually, since for Guids I don't care what the ID actually is, I have another extension method:
public static T WithNewGuid<T>(this T o) where T : class, IHasID<Guid>
{
if (o == null) return o;
o.GetType().InvokeMember("ID", BindingFlags.SetProperty | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, o, new object[] { Guid.NewGuid() });
return o;
}
And in usage:
var testUser = new User("Test User").WithNewGuid();
Instead of trying to mock out your repository, I'd suggest you try to use an in-memory SQLite database for testing. It will give you the speed you're looking for and it will make things a lot easier too. If you want to see a working sample you can have a look at one of my GitHub projects: https://github.com/dlidstrom/GridBook.

Categories

Resources