Simple question for I bet a not so simple answer.
Think of a project like Wordpress. The base of Wordpress is great and the developers built it to be extended with widgets or plugins etc.
Now think NHibernate, specifically with Fluent Mappings.
Put them together and you have a great and stable "base" system BUT how do you load mappings presented from external assemblies? I realize that the system would have to load the Assemblies on the fly using reflection but how do you configure nHibernate, Fluently, at first run to realize that there are extra entities to be loaded from those assemblies? How do you reference them?
I know you can;t add Mappings at run-time after the configurations is made, well you have to recreate the SessionFactory. This is why I want to load all required entities at runtime.
I also know that this can be somewhat accomplished with Dependancy Injection but I do not wish to go that route nor want the extreme baggage that comes with it.
If the plain old nHiberante config file can be modified and then referenced at runtime to reflect new Entities I can only assume there has to be a way to do it Fluently.
Also, based on answers: do you make the configuration from the base project or a DATA ACCESS assembly?
Thanks for your help.
You can pass an NHibernate Configuration object to Fluently.Configure(). That way you can update the configuration. You need to re-create the session factory when you do that, like you said.
You can scan the assemblies in the bin folder for assemblies that contain fluent mapping classes (Assembly.Load, then check
Assembly.GetExportedTypes()
.Any(x => x.IsClass
&& !x.IsAbstract
&& typeof(IMappingProvider).IsAssignabledFrom(type))
or similar) and add the assembly. When all assemblies are scanned, (re-)create the session factory.
I'm doing something similar in an extensible application framework I have written (although I've moved to from Fluent NHibernate to NHibernate mapping by code, but the principles are similar).
Related
I am trying to understand Microsoft.practices.Unity.
So, I have this solution:
webproject
business classlibrary project as my logic tier
data classlibrary project as my data access tier
And I want to use Unity to separate web tier from logic and separate logic tier from data, using DI.
I have created an unity.config file in my web project, cause I wanna control the registration from a configuration file, and not inside binary code. This is OK for me. I am using Unity.MVC4.
But, with that, I only resolve my dependency injection only from web to business tier. And how can I make the same thing for business to data tier ?
I have already seen some web examples but I am still confused, because no example shows me the process through the web tier to data tier, step by step, to understand how to implement the Unity DI.
I would like to see a simple example, with a n-tier solution with total DI implementation with Unity.
Prevent from using the config file for registration of dependencies. This is brittle and error prone and you can only do a subset of things that you can do in code. If you're doing this because you want to prevent dependency references, please note that by using the config file, the same referencing still applies, but now it's implicit and there's no compile time checking to help you.
This doesn't mean though that you should never use the config file, but you should only use it to configure things that can actually change during or after deployment. Most things shouldn't change during that time, since most changes must be changed by a developer, either manually by starting the application, or in an automated fashion using unit tests.
Neither would place class names in the config file for the same reason as it is brittle. Using configuration switches is usually much better, since this allows you to move the class names to the code (with a switch case statement or if statement to change configuration based on the config setting) and enables compile time checking.
For the rest of your questions, Tuzo's link will probably give you enough information.
I was having issues with a model not syncing with what Entity Framework thought was the current version so I wiped out all the migrations and started over as per this post.
After the reset. I went to enable Entity Framework and it gave this error.
More than one context type was found in the assembly 'Proj'. To
enable migrations for Proj.Models.UsersContext, use
Enable-Migrations -ContextTypeName Proj.Models.UsersContext. To
enable migrations for Proj.Models.InjuriesContext, use
Enable-Migrations -ContextTypeName PamperWeb.Models.InjuriesContext. ...for all my contexts
I was able to enable the first context, Users, but then when I tried to enable another I get an error saying
Migrations have already been enabled in project 'Proj'. To
overwrite the existing migrations configuration, use the -Force
parameter.
Apparently I am way off in how MVC and Entity Framework work. I have contexts set up in each of my model classes. Should I just have one Context and all my DBsets in that context? If so does it matter which model class file this one context goes with? All my current context's point to the same database.
In normal application you should have single context with db sets for all your model classes. The context class should be in its own file. The context forms your whole model and gives you access to the database. It provides a lot of out-of-the-box functionality but the functionality is offered only for model classes registered in your context. If you divide model classes into separate contexts you lose some of the out-of-the-box functionality when working with entities loaded from different contexts.
I've downloaded the fluent hibernate 1.2 zip file from the website.
It contains various files, amongst them
NHibernate.dll
FluentNHibernate.dll
Castle.Core.dll
Remotion.Data.Linq.dll
Antlr3.Runtime.dll
Iesi.Collections.dll
NHibernate.ByteCode.Castle.dll
Q1) Are all these files required for doing a simple application?. By simple I mean that the db contains a few tables that doesn't need complicated queries and has limited levels/amounts of reference keys and joins.
Q2) Does fluent nHibernate run on mono on linux?
no; see here for what's needed and what's optional.
it runs wherever you can run (and develop) .net programs (i.e it, obviouslly, needs .net runtime environment).
Is there any way for me to generate an nHibernate configuration file from a Configuration instance (that has been already configured by some external code?). I'm looking for an easy way to mimic this external code with a static XML file?
(I guess similar to the "ExportTo" method that Fluent nHibernate has for fluent mappings - but acting on the resulting Configuration object instead).
Thank you!
No, there is no way to do that easily.
What can be done (and is common) is binary serialization of the configuration. Check http://github.com/ayende/Effectus/blob/master/Effectus/Infrastructure/BootStrapper.cs
NInject's module architecture seems useful but I'm worried that it is going to get in a bit of a mess.
How do you organise your modules? Which assembly do you keep them in and how do you decide what wirings go in which module?
Each subsystem gets a module. Of course the definition of what warrants categorisation as a 'subsystem' depends...
In some cases, responsibility for some bindings gets pushed up to a higher level as a lower-level subsystem/component is not in a position to make a final authoritative decision - in some cases this can be achieved by passing parameters into the Module.
Replying to my own post after a couple of years of using NInject.
Here is how I organise my NInjectModules, using a Book Store as an example:
BookStoreSolution
Domain.csproj
Services.csproj
CustomerServicesInjectionModule.cs
PaymentProcessingInjectionModule.cs
DataAccess.csproj
CustomerDatabaseInjectionModule.cs
BookDatabaseInjectionModule.cs
CustomSecurityFramework.csproj
CustomSecurityFrameworkInjectionModule.cs
PublicWebsite.csproj
PublicWebsiteInjectionModule.cs
Intranet.csproj
IntranetInjectionModule.cs
What this is saying is that each project in the system comes prepackaged with one or more NInject modules that know how to setup the bindings for that project's classes.
Most of the time an individual application is not going to want to make significant changes to the default injection modules provided by a project. For example, if I am creating a little WinForm app which needs to import the DataAccess project, normally I am also going to want to have all the project's Repository<> classes bound to their associated IRepository<> interfaces.
At the same time, there is nothing forcing an individual application to use a particular injection module. An application can create its own injection module and ignore the default modules provided by a project that it is importing. In this way the system still remains flexible and decoupled.