Injecting ISession in FluentValidation AbstractValidator - fluentvalidation

Trying to work out the best way of getting NHibernate ISession into a fluent validation abstract validator. Issue is that ISession is registered as per web request and validators are registered as singleton as per fluent's best practices for performance reasons. This obviously causes issues with ISession being disposed before its needed.
Any tips greatly appreciated, trying to avoid passing in the container instance

You could use the TypedFactoryFacility, the easiest is to use a delegate, see http://stw.castleproject.org/Windsor.Typed-Factory-Facility-delegate-based-factories.ashx
I would however suggest using interface based factories because firstly you can explicitly release the session when you're done with it, and secondly it's more evident in the code what you're doing, see http://stw.castleproject.org/Windsor.Typed-Factory-Facility-interface-based-factories.ashx

Related

Single repository with generic methods ... bad idea?

I'm currently trying out a few different ways of implementing repositories in the project I'm working on, and currently have a single repository with generic methods on it something like this:
public interface IRepository
{
T GetSingle<T>(IQueryBase<T> query) where T : BaseEntity;
IQueryable<T> GetList<T>(IQueryBase<T> query) where T : BaseEntity;
T Get<T>(int id) where T : BaseEntity;
int Save<T>(T entity) where T : BaseEntity;
void DeleteSingle<T>(IQueryBase<T> query) where T : BaseEntity;
void DeleteList<T>(IQueryBase<T> query) where T : BaseEntity;
}
That way I can just inject a single repository into a class and use it to get whatever I need.
(by the way, I'm using Fluent NHibernate as my ORM, with a session-per-web-request pattern, and injecting my repository using Structuremap)
This seems to work for me - the methods I've defined on this repository do everything I need. But in all my web searching, I haven't found other people using this approach, which makes me think I'm missing something ... Is this going to cause me problems as I grow my application?
I read a lot of people talking about having a repository per root entity - but if I identify root entities with some interface and restrict the generic methods to only allow classes implementing that interface, then aren't I achieving the same thing?
thanks in advance for any offerings.
I'm currently using a mix of both generic repositories (IRepository<T>) and custom (ICustomRepository). I do not expose IQueryable or IQueryOver from my repositories though.
Also I am only using my repositories as a query interface. I do all of my saving, updating, deleting through the Session (unit of work) object that I'm injecting into my repository. This allows me to do transactions across different repositories.
I've found that I definitely cannot do everything from a generic repository but they are definitely useful in a number of cases.
To answer your question though I do not think it's a bad idea to have a single generic repository if you can get by with it. In my implementation this would not work but if it works for you then that's great. I think it comes down to what works best for you. I don't think you will ever find a solution out there that works perfectly for your situation. I've found hybrid solutions work best for me.
I've done something similar in my projects. One drawback is that you'll have to be careful you don't create a select n+1 bug. I got around it by passing a separate list of properties to eagerly fetch.
The main argument you'll hear against wrapping your ORM like this is that it's a leaky abstraction. You'll still have to code around some the "gotchas" like select n+1 and you don't get to take full advantage of things like NH's caching support (at least not without extra code).
Here's a good thread on the pros and cons of this approach on Ayende's blog. He's more or less opposed to the pattern, but there are a few counter arguments too.
I've implemented such kind of repository for NHibernate. You can see example here.
In that implementation you are able to do eager loading and fetching. The pitfall is that with NH you will often need to be able to use QueryOver or Criteria API to access data (unfortunately LINQ provider is still far from being perfect). And with such an abstraction it could be a problem leading to leaky abstraction.
I have actually moved away from repository pattern and creating a unit of work interfaces - I find it limiting.
Unless you anticipate a change in the datastore i.e. going from DB to textfile or XML - which has never been the case for me, you are best off using ISession. You are trying to abstract your data access and this is exactly what NHibernate does. Using repository limits really cool features like Fetch(), FetchMany() futures etc. ISession is your unit of work.
Embrace NHibernate and use the ISession directly!
I've used this approach successfully on a few projects. It gets burdensome passing in many IRepository<T> to my Service layers for each BaseEntity, but it works. One thing I would change is put the where T : on the interface rather than the methods
public interface IRepository<T> where T : BaseEntity

Antipatterns of IoC container usage. Why IoC containers are so complex and used so "fancy" way?

I'm seriously start thinking that usage of IoC container provokes to create overdesigned solutions (at least it provokes me to try to use various unnecessary features:).
It's the time to synchronize my "IoC" antipatterns list with community one's..
My short experience tell that it is absolutely enough to call Resolve method once per application at startup to resolve some infrastructure singletons and initiate with them "transient object's factory" that could produce new "smaller life time grain factories" . Even to make those factories thread safe (e.g. create one instance per thread) is so easy to achieve by adding 10 code lines into factory... Still those factories are much more simpler then "library's integration with IoC tool". Interception? Just create your own wrappers... Life time managers / dependency strategies/ parent containers? Call the Resolve only once at bootstrapper and you won't think about that.
Could you help me to understand why developers call Resolve several times on different application layers (by passing container or by passing delegate to container) and then have a lot of things to think about? I really worry that I miss something.
Some kind of IoC are anti-patterns or may be in some cases. For example the service locator antipattern. But if you are using constructor injection at the beginning of your application - and only there - then it should not lead to an anti-pattern.
Injecting a DI container interface in a class is a wrong use of constructor injection. If DI is not part of the business logic of your class it should not know or depend on DI container nor should it depend on IKitchen. It's only fine to inject your DI container in some kind of helper or service working in conjunction with your dependency injection container, because it's purpose is to work with or around DI container. The examples in the links you give are misuse of IoC. It does not mean that IoC in general is an anti-pattern.
I think the correct question would be "Can constructor injection be an anti-pattern?". So far I've never faced any situation or seen any example where it was so I would say "no", until I face such a situation.
When it was not clear to me how to use an IoC container, I decided to stop using it, because I thought was just an overcomplication over the simple dependency injection.
It is true though that even without IoC is possible to fall in the over-injection cases.
A while ago I read some posts from the author of ninject that opened my mind.
As you already know the injector should be used only inside the context root. However, in order to avoid over-injections, I decided to introduce an exception of the rule for injected factories.
In my framework, factories (and only factories) can use the injector container. Factories are binded in the container in the context root and therefore can be injected. Factories become valid dependencies and are used to create new objects inside other objects, using the injector container to facilitate dependencies injection.
Read This
Clearly something wrong. New library should not bring additional complex code.
I've found somebody who possibly could understand me :)
Constructor over-injection anti-pattern
Other antipattern in my eyes is pushing the initialization of container "deeper" then actual bootsrapper.
For example Unity and WCF recommendations
Bootstrapper in wcf app is the service constructor, then just put container initialization to constructor. I do not understand reasons to recommend to go for programming wcf sevice behaiviors and custome sevice host factory: if you want to have "IoC container free" bootstrapper - it is absurd, if you need to have "IoC container free" service contract implementation - just create second "IoC container free" service contract implementation.

Entity Framework - implementing IDbSet

I would like to implement IdbSet to provide my DbContext a custom implementation that will essentially serve to filter my data for the currently logged in user (I am working on a multi-tenant application). The general idea I am going with is very similar to this post: Can a DbContext enforce a filter policy?
However, it is not clear to me how to make DbContext "know" about how to use my own class that implements IDbSet. I am having a tough time finding documentation on this. Any pointers would be helpful!
TIA,
-jle
I'm almost sure that you cannot create your own implementation of IDbSet and pass it to entity framework. Such implementation will lose all stuff related to EF which is internally implemented in DbSet itself - by internally I really mean that there is no public API to replace it. IDbSet interface is provided not because it is supposed to create your own sets but because it allows mocking sets when unit testing application. The only way you can extend functionality is either:
Inheriting DbSet but I'm afraid that it will not help you as well because methods / properties will not be marked as virtual.
Creating custom IDbSet implementation which will wrap DbSet. This looks like the best chance but you can still find that DbContext doesn't like your new implementation. I gave this very quick try but I was not successful. My implementation worked for persisting but not for querying.

Implementing repositories using NHibernate and Spring.Net

I'm trying to get to grips with NHibernate, Fluent NHibernate and Spring.
Following domain-driven design principals, I'm writing a standard tiered web application composed of:
a presentation tier (ASP.Net)
a business tier, comprising:
an application tier (basically a set of methods made visible to UI tier)
repository interfaces and domain components (used by the application tier)
A persistence tier (basically the implementation of the repository interfaces defined in the business tier)
I would like help determining a way of instantiating an NHibernate ISession in such a way that it can be shared by multiple repositories over the lifetime of a single request to the business tier. Specifically, I would like to:
allow the ISession instance and any transaction to be controlled outwith the repository implementation (perhaps by some aspect of the IOC framework, an interceptor?)
allow the ISession instance to be available to the repositories in a test-friendly manner (perhaps via injection or trough some shared 'context' abstraction)
avoid any unnecessary transactions being created (i.e. when only read-only operations have been executed)
allow me to write tests that use SQLLite
allow me to use Fluent NHibernate
allow the repository implementation to remain ignorant of the host environment. I don't yet know if the businese tier will run in-process with the presentation tier or will be hosted separately under WCF (in IIS), so I don't want to bind my code too closely to a HTTP context (for example).
My first attempt to solve this problem had been using the Registry pattern; storing the ISession instance in a ThreadStatic property. However, subsequent reading has suggested that isn't the best solution (as ASP.Net can switch the thread within the page lifecycle, I believe).
Any thoughts, part solutions, pattern names, pointers to up-to-date samples (NHibernate 2) will be most gratefully received.
I have not used Spring.NET so I can't comment on that. However, the rest sounds remarkably (or perhaps not so remarkably; we're hardly the first to implement these things ;) similar to my own experience. I too had trouble finding a One True Best Practice so I just read as much as I could and came up with my own interpretation.
In my situation I wanted transaction/session management to be external to the repository as well as keep repository concerns from bubbling up out of them (i.e. the code using the repository should not need to know that it's using NHibernate internally and shouldn't need to know anything about NHibernate session management). In my case it was decided that transactions would be created by default lest developers forget them, so I had to have a read-only escape mechanism. I went with the Unit of Work pattern with the NHibernate ISession instance store inside. Calling code (I also created a DSL interface for the UoW) might look something like:
using (var uow = UoW.Start().ReadOnly().WithHttpContext()
.InNewScope().WithScopeContext(ScopeContextProvider.For<CRMModel>())
{
// Repository access
}
In practice, that could be as short as UoW.Start() depending on how much context is already available. The HttpContext part refers to the storage location for the UoW which is, unsurprisingly, the HttpContext in this case. As you mentioned, for a ASP .NET application, HttpContext is the safest place to store things. ScopeContextProvider basically makes sure the right data context is provided for the UoW (ISession instance to the appropriate database/server, other settings). The "ScopeContext" concept also makes it easy to insert a "test" scope context.
Going this route makes the repositories explicitly dependent on the UoW interface. Actually, you might be able to abstract it some but I'm not sure I see the benefit. What I mean is, each repository method retrieves the current UoW instance and then pulls out the ISession object (or simply a SqlConnection for those methods that don't use NHibernate) to run the NHibernate query/operation. This works for me though because it also seems like the ideal time to make sure that the current UoW is not read-only for methods that might need to run CRUD.
Overall, I think this is one approach that solves all your points:
Allows session management to be external to the repository
ISession context can be mocked or pointed at a context provider for a test environment
Avoids unnecessary transactions (well, you'd have to invert what I did and have a .Transactional() call or something)
I can't see why you couldn't test with SQLite since that's more of an NHibernate concern
I use Fluent NHibernate myself
Allows the repository to be ignorant of the host environment (that is, the repository caller controls the UoW storage context)
As for the UoW implementation, I'm partially kicking myself for not looking around more before I started. There's a project called machine.uow which I understand is fairly popular and works well with NHibernate. I haven't played with it much so I can't say if it solves all my requirements as neatly as the one I wrote myself, but it might have saved development time as well.
Perhaps we'll get some comments as to where I went wrong or how to improve things, but I hope this is at least helpful in some way.
For reference, the software stack I'm using is:
ASP.NET MVC
Fluent NHibernate on top of NHibernate
Ninject for dependency injection
What you are describing is supported by the Spring.NET framework almost out of the box. Only for FluentNHibernate you need to add a custom SessionFactory (not a lot of code, look here:Using Fluent NHibernate in Spring.NET) to Spring.NET.
Every repository can use the same ISession, just inject the SessionFactory in your repositories and use Spring.NET's transaction services.
Just try it out, they have pretty thorough documentation imho.

Dependency injection with NHibernate objects

I am wondering how to tell NHibernate to resolve dependencies on my POCO domain objects.
I figured out that methods like CalculateOrderTax should be in the Domain object because they encode domain specific business rules. But once I have two of those I am violating SRP.
It would be no problem to extract those methods to Strategy classes, but I wonder how to make NHibernate load those.
It doesn't seem like a good solution to loop through a list of objects in the repository to do get/set based Dependecy injection before handing the object off to the higher layers.
I am also using Castle Windsor for my Depency injection right now.
I've been using interceptors for similar tasks:
An interceptor that modifies loaded entities:
public class MyInterceptor : EmptyInterceptor
{
public override bool OnLoad(object entity, object id, object[] state, string[] propertyNames, IType[] types)
{
return InjectDependencies(entity as MyEntity);
}
}
Associate it with a session:
nhSessionFactory.OpenSession(myInterceptor);
I've also read somewhere that there would be better support for custom constructor injection in the upcoming 2.1 release but I can't seem to find the reference right now.
As no-one seems to be able to answer your question at the moment I thought I'd suggest restructuring your code to remove the need for the Order to calculate it's own tax.
You could delegate it to a OrderTaxService which takes an Order object and returns an OrderValue object or something along those lines.
This will keep the logic in your domain but remove the need to attach it to your Order objects.
I agree with Garry that you should remove service dependencies from your domain objects as much as possible. Sometimes it makes sense, such as encryption/decryption. In that case you can hide it in the infrastructure using interception or IUserType. I think the latter is favorable when you can use it. This article shows in detail how to do it. I am doing this and it works quite fine.