Unity constructor injection not resolving repositories as expected - dependency-injection

I'm using Unity to resolve Mike Hadlow's implementation of generic repositories (linq to sql flavor) targeting multiple databases. The container configuration that works:
container.RegisterType<IConnectionStringProvider, HistoryConnectionProvider>(new TransientLifetimeManager())
.RegisterType<IConnectionStringProvider, MetaConnectionProvider>("meta", new TransientLifetimeManager())
.RegisterType<IDataContextProvider, DataContextProvider>(new TransientLifetimeManager())
.RegisterType<IDataContextProvider, DataContextProvider>("meta", new TransientLifetimeManager(), new InjectionConstructor(new ResolvedParameter<IConnectionStringProvider>("meta")))
// this registration of Repository<> resolves the history database by default
.RegisterType(typeof(IRepository<>), typeof(Repository<>), new TransientLifetimeManager());
// anything not targeting this database has to be declared
.RegisterType<IRepository<SpecificType>, Repository<SpecificType>>(new TransientLifetimeManager(), new InjectionConstructor(new ResolvedParameter<DataContextProvider>("meta")));
This seems unnecessarily verbose. So I'm currently trying different approaches. Using individual interfaces for each database:
IConnectionStringProvider historyConnectionProvider = new ConnectionProvider(connections.HistoryConnectionString);
IConnectionStringProvider metaConnectionProvider = new ConnectionProvider(connections.MetaConnectionString);
container.RegisterType<IDataContextProvider, DataContextProvider>("history", new TransientLifetimeManager(), new InjectionConstructor(historyConnectionProvider))
.RegisterType<IDataContextProvider, DataContextProvider>("meta", new TransientLifetimeManager(), new InjectionConstructor(metaConnectionProvider))
.RegisterType(typeof(IHistoryRepository<>), typeof(Repository<>), new TransientLifetimeManager(), new InjectionConstructor(new ResolvedParameter<IDataContextProvider>("history")))
.RegisterType(typeof(IMetaRepository<>), typeof(Repository<>), new TransientLifetimeManager(), new InjectionConstructor(new ResolvedParameter<IDataContextProvider>("meta")));
Unfortunately, this doesn't work. The result is the last type of IDataContextProvider registered getting injected into every type of Repository. Thanks in advance for any help.

Daniel, on the second set of code what is the purpose of naming the separate registrations? You already have decided to have separate interfaces for each database so there doesn't seem to be a need to have a name on it as well. I could be misunderstanding though. Moreover, in the second example, if Respository can fulfill the interface for both IMeta and IHistory, then it begs the question what is the difference between the two.
Had i given you example code how to achieve what you want, it would look very similar to the first example you had which in reality isn't all that much more verbose than the latter.

Solution to the original question
Unity needed a unique type, as well as interface. I'm still unsure as to why constructor injection didn't handle this. This works:
// where IMetaRepository<T> and MetaRepository<T> both are derived place holders
container.RegisterType(typeof(IMetaRepository<>), typeof(MetaRepository<>), new TransientLifetimeManager());
Unfortunately, this sets up a situation where consuming classes need knowledge of where their data is coming from, which I wasn't happy with.
Better Design
I wanted to leave my dbmls generated (so this ruled out making my models adhere to a certain interface), so I just threw them in different sub folders, causing the designer to generate a different namespace for each database.
Then, in my Repository implementation, I did the following:
public Repository(IConnections connections)
{
T type = new T();
var ns = type.GetType().Namespace;
if (ns == "Project.Common.DAL.History")
{
_dataContext = new DataContext(connections.HistoryConnectionString);
}
else if (ns == "Project.Common.DAL.Transaction")
{
_dataContext = new DataContext(connections.TransactionConnectionString);
}
else
{
_dataContext = new DataContext(connections.MetaConnectionString);
}
}
I think one step past this would be to build a custom type resolver for unity to check the namespace for me and return to injecting the data context (this will be necessary before unit of work can be implemented). I'm not going to mark this as the answer quite yet in case someone has a better solution.

Related

Using NHibernate.AspNet.Identity

I am attempting to use Asp.net identity and NHibernate.
I have created a new blank Asp.net MVC site using .NET framework 4.5.1 and I have installed and followed the instructions for using nuget package NHibernate.AspNet.Identity as described here:
https://github.com/milesibastos/NHibernate.AspNet.Identity
which involves making the following changes to the AccountController class default constructor:
var mapper = new ModelMapper();
mapper.AddMapping<IdentityUserMap>();
mapper.AddMapping<IdentityRoleMap>();
mapper.AddMapping<IdentityUserClaimMap>();
mapper.AddMapping<IdentityUserLoginMap>();
var mapping = mapper.CompileMappingForAllExplicitlyAddedEntities();
var configuration = new Configuration();
configuration.Configure(System.Web.HttpContext.Current.Server.MapPath(#"~\Models\hibernate.cfg.xml"));
configuration.AddDeserializedMapping(mapping, null);
var schema = new SchemaExport(configuration);
schema.Create(true, true);
var factory = configuration.BuildSessionFactory();
var session = factory.OpenSession();
UserManager = new UserManager<ApplicationUser>(
new UserStore<ApplicationUser>(session));
I am getting the following exception:
No persister for: IdentityTest.Models.ApplicationUser
The ApplicationUser class doesn't have any additional properties to IdentityUser (which works fine for a Entity Framework implementation of Asp.net Identity).
Can anyone offer suggestions as to how I can get Asp.net identity to work with this NuGet package?
I have struggled very much with this library, which is making me question why this is the recommended library for using OWIN with NHibernate.
Anyway, to answer your question, the code you provided that you got from the github website adds NHibernate mappings for the library's classes. NHibernate doesn't have a mapping for ApplicationUser, it only has a mapping for it's base class. NHibernate needs a mapping for the instantiated class. This is problematic because you don't have access to the mapping code in the library's assembly, so you can't change it to use the ApplicationUser class instead. So the only way to get past this using the library as it is, is to remove the ApplicationUser class and use the library's IdentityUser class. Or, you could copy the mapping code from github and try using the same mapping for ApplicationUser.
Also, the library code and the code he gives for the AccountController does not ever open an NHibernate transaction, so even though the library calls Session.Save and Session.Update the data won't ultimately be saved in the database. After you open the session you need to open a transaction and save it as a private field on the class:
transaction = session.BeginTransaction(IsolationLevel.ReadCommitted);
Then you need to call transaction.Commit() after your action in the AccountController finishes executing, so you will need to override OnResultExecuted:
protected override void OnResultExecuted(ResultExecutedContext filterContext)
{
transaction.Commit();
}
Keep in mind this example is oversimplified, and in a production application you need to have error checking where you will Rollback instead of Commit if there are errors, and you need to properly close/dispose of everything, etc.
Furthermore, even after you solve those problems, there are other issues with the library. I ended up having to download the source from github so I could modify the library in order to use it. There are at least 3 other blatant errors in the library's code:
1) In NHibernate.AspNet.Identity.UserStore:
public virtual async Task<TUser> FindAsync(UserLoginInfo login)
{
this.ThrowIfDisposed();
if (login == null)
throw new ArgumentNullException("login");
IdentityUser entity = await Task.FromResult(Queryable
.FirstOrDefault<IdentityUser>(
(IQueryable<IdentityUser>)Queryable.Select<IdentityUserLogin, IdentityUser>(
Queryable.Where<IdentityUserLogin>(
// This line attempts to query nhibernate for the built in asp.net
// UserLoginInfo class and then cast it to the NHibernate version IdentityUserLogin,
// which always causes a runtime error. UserLoginInfo needs to be replaced
// with IdentityUserLogin
(IQueryable<IdentityUserLogin>)this.Context.Query<UserLoginInfo>(), (Expression<Func<IdentityUserLogin, bool>>)(l => l.LoginProvider == login.LoginProvider && l.ProviderKey == login.ProviderKey)),
(Expression<Func<IdentityUserLogin, IdentityUser>>)(l => l.User))));
return entity as TUser;
}
2) In NHibernate.AspNet.Identity.DomainModel.ValueObject:
protected override IEnumerable<PropertyInfo> GetTypeSpecificSignatureProperties()
{
var invalidlyDecoratedProperties =
this.GetType().GetProperties().Where(
p => Attribute.IsDefined(p, typeof(DomainSignatureAttribute), true));
string message = "Properties were found within " + this.GetType() +
#" having the
[DomainSignature] attribute. The domain signature of a value object includes all
of the properties of the object by convention; consequently, adding [DomainSignature]
to the properties of a value object's properties is misleading and should be removed.
Alternatively, you can inherit from Entity if that fits your needs better.";
// This line is saying, 'If there are no invalidly decorated properties,
// throw an exception'..... which obviously should be the opposite,
// remove the negation (!)
if (!invalidlyDecoratedProperties.Any())
throw new InvalidOperationException(message);
return this.GetType().GetProperties();
}
3) In NHibernate.AspNet.Identity.UserStore: For some reason, at least when creating a user/user login using an external provider like facebook, when the user/user login is initially created, the Update method is called instead of the Add/Create causing NHibernate to try to update an entity that doesn't exist. For now, without looking more into it, in the UserStore update methods I changed the library's code to call SaveOrUpdate on the NHibernate session instead of Update which fixed the problem.
I have only ran simple tests with the library that have worked after my changes, so there is no telling how many other runtime / logic errors are in this library. After finding those errors, it makes me really nervous using it now. It seems there was absolutely no testing done with even simple scenarios. Take caution using this library.
I also struggled to use NHibernate.AspNet.Identity. I found it was much easier just to make my own implementation using NHibernate, which I've turned into a minimal worked example here:
https://github.com/MartinEden/NHibernate.AspNet.Identity.Example
They key parts are a simple implementation of IUserStore<TUser, TKey> and IUserPasswordStore<TUser, TKey> using an NHibernate session for persistence. Then it's just a matter of writing a bit of glue to tell Owin to use that code.

Where should my object construction code be while respecting the Law of Demeter?

I've been watching Google's clean code talks by Misko Hevery. These talks say: ask for dependencies in the constructor, so other programmers can see exactly what is needed up front, to instantiate an instance of a given object (law of demeter). This also makes testing easier as a programmer knows exactly what needs to be mocked.
Example time
If I have a class Customer and I also have a CustomerDAO class to abstract data access away. When I construct a customer object I might do the following:
database = new Database('dsn');
customerDao = new CustomerDAO(database);
customer = new Customer(customerDao);
This might happen in my controller. I can simplify this object construction via use of a dependency injection container. Below I've used a DI container to obtain an instance of my database class, as that is widely used throughout my application. This reduces the construction code to one place and can be mocked for testing.
Should I be adding my domain class dependencies (in this case DAO objects) to my DI container? If my application is large, will this make my DI container huge?
Using a DI container my code might look like this:
// container setup
container->dsn = '...';
container->dbh = function($c) {
return new Database($c->dsn);
};
container->customerDao = function($c) {
return new CustomerDAO($c->dbh);
};
// controller code
class ControllerCustomer extends ControllerBase {
public function index() {
container = this->getContainer();
customer = new Customer(container->customerDao);
view->customerName = customer->getName();
view->render();
}
}
Seems to be OK, if another programmer wants to test Customer, they need only mock CustomerDAO.
Taking this example a step further, if I have domain classes with dependencies on other domain classes, surely my DI container should not need to know how to construct every domain class? For example:
My customer might be a company/institution and therefore have many users.
class Customer {
protected _dao;
public function Customer(dao) {
_dao = dao;
}
public function listUsers() {
userIds = _dao->getAllUserIds();
users = array();
foreach (userIds as uid) {
user = new User(new UserDAO(new Database('dsn')); // problem
users[] user->load(uid);
}
return users;
}
}
Problems
As I've not passed my DI container to my Customer object, it can't create user objects as shown above as it has no reference to the database DSN (and shouldn't really need to know how to make users)
Creating it's own dependencies makes this code untestable as they're concrete with no seams for mocking.
If I do pass the container to my Customer class, does this make my interface for Customer lie? (See 9:15 in the linked Google video).
Should I be passing a user factory to Customer to enable it to construct User objects?
database = new Database('dsn');
userDao = new UserDAO(database);
userFactory = new UserFactory(userDao);
customer = new Customer(customerDao, userFactory);
Should the construction for UserFactory be in my DI container?
If I am interpreting this correctly, it seems like your question is actually about entity construction and lifecycle management.
DDD is one design approach which provides very prescriptive guidance on how to approach problems like these; in your case the relevant concepts are repositories and aggregate roots. While DDD probably won't answer your question directly, it will make it much easier for you to come up with a pattern-based solution which matches your requirements.
I'm purposely not attempting to explain DDD in general or the concepts I mentioned; there is enough material about that available on SO and elsewhere.

Managing multiple databases with NHibernate and Autofac

I thought I'd get this question out there while I noodled on a solution on my own.
After having built out the bulk of an application, I have a last minute requirement to support reading/writing to an additional database (2 total, no known others). I built the application using NHibernate, with Autofac supplying the DI/IoC components. FWIW, this resides in an ASP.NET MVC 2 app.
I have a generic repository class that takes an NHibernate session. Theoretically, I can continue to use this generic repository (IRepository<>) for the second database so long as the session that gets passed to it is spawned from an appropriate SessionFactory, right?
Well, when the app starts, Autofac does it's thing. With regards to the Session and SessionFactory, I have a module that states:
builder.Register(c => c.Resolve<ISessionFactory>().OpenSession())
.InstancePerMatchingLifetimeScope(WebLifetime.Request)
.OnActivated(e =>
{
e.Context.Resolve<TransactionManager>().CurrentTransaction = ((ISession)e.Instance).BeginTransaction();
});
builder.Register(c => ConfigureNHibernate())
.SingleInstance();
where ConfigureNHibernate(), which returns the base SessionFactory, looks like:
private ISessionFactory ConfigureNHibernate()
{
Configuration cfg = new Configuration().Configure();
cfg.AddAssembly(typeof(Entity).Assembly);
return cfg.Configure().BuildSessionFactory();
}
Currently, this is limited to just the one database. In any other NHib scenario, I'd likely shove instances of the separate SessionFactories into a hash, and retrieve them as needed. I don't want to have to re-architect the whole thing as we're fairly close to a major release. So, I'm guessing I need to modify at least the methods above so that I can independently configure two SessionFactories. My gray area is how I'll go about specifying the correct Factory be used with a specific repository (or at least for entities specific to that second database).
Anyone have experience with this scenario while using an IoC container and NHibernate in this manner?
EDIT
I've stubbed out a GetSessionFactory method that takes a configuration file path, checks for the existance of a matching SessionFactory in the HttpRuntime.Cache, creates a new instance if one doesn't already exist, and returns that SessionFactory. Now I still need to hammer out how to tell Autofac how and when to specify an appropriate config path. The new method looks like (borrowed heavily from Billy's 2006 post here):
private ISessionFactory GetSessionFactory(string sessionFactoryConfigPath)
{
Configuration cfg = null;
var sessionFactory = (ISessionFactory)HttpRuntime.Cache.Get(sessionFactoryConfigPath);
if (sessionFactory == null)
{
if (!File.Exists(sessionFactoryConfigPath))
throw new FileNotFoundException("The nhibernate configuration file at '" + sessionFactoryConfigPath + "' could not be found.");
cfg = new Configuration().Configure(sessionFactoryConfigPath);
sessionFactory = cfg.BuildSessionFactory();
if (sessionFactory == null)
{
throw new Exception("cfg.BuildSessionFactory() returned null.");
}
HttpRuntime.Cache.Add(sessionFactoryConfigPath, sessionFactory, null, DateTime.Now.AddDays(7), TimeSpan.Zero, System.Web.Caching.CacheItemPriority.High, null);
}
return sessionFactory;
}
I'm assuming that you want different types of entities to go into each database; if you want to keep the same kinds of entities in each database, check out AutofacContrib.Multitenant.
The two ingredients that can help with this scenario are:
Named services http://code.google.com/p/autofac/wiki/TypedNamedAndKeyedServices
Resolved parameter http://code.google.com/p/autofac/wiki/ResolveParameters (minimal docs on this one - the coming Autofac 2.4 release has some syntax sweeteners around this...)
First, use named services to refer to the two different databases. I'll call them "db1" and "db2". All of the components relating to the database, all the way up to the session, get registered with a name:
builder.Register(c => ConfigureDb1())
.Named<ISessionFactory>("db1")
.SingleInstance();
builder.Register(c => c.ResolveNamed<ISessionFactory>("db1").OpenSession())
.Named<ISession>("db1")
.InstancePerLifetimeScope();
// Same for "db2" and so-on.
Now, assuming you have a type NHibernateRepository<T> that accepts an ISession as its constructor parameter, and that you can write a function WhichDatabase(Type entityType) that returns either "db1" or "db2" when given the type of an entity.
We use a ResolvedParameter to dynamically choose the session based on the entity type.
builder.RegisterGeneric(typeof(NHibernateRepository<>))
.As(typeof(IRepository<>))
.WithParameter(new ResolvedParameter(
(pi, c) => pi.ParameterType == typeof(ISession),
(pi, c) => c.ResolveNamed<ISession>(
WhichDatabase(pi.Member.DeclaringType.GetGenericArguments()[0])));
(Warning - compiled and tested in Google Chrome ;))
Now, resolving IRepository<MyEntity> will select the appropriate session, and sessions will continue to be lazily initialised and correctly disposed by Autofac.
You will have to think carefully about transaction management of course.
Hope this does the trick!
NB

What's the simplest way to intercept a method call for added functionality?

Suppose i have a repository that returns a list of Posts. The repository interface has a GetAll() method which does what it suggests.
Now in keeping with the theory that i shouldn't be putting domain logic in the repository, i want to intercept calls to the concrete GetAll() method such that i can add the following logic to the GetAll() result:
return GetAll().OrderByDescending(p => p.Posted).ToList();
The reason i want to intercept this is because (1) i don't want to have the client remember to call an extension method (OrderByDescending or some useless wrapper of that), i want it called every time and (2) i don't want to have all my concrete implementations have to remember to order the GetAll() result - i want this logic in a single place external to any repository.
What's the easiest way to do this?
I'm already using StructureMap so if i can intercept with this it might be a low cost option. But i don't think SM intercepts method calls, just the creation of the object instance?
Do i need to go to a proxy or mixin pattern? Do i need to go all-in with Castle Dynamic Proxy? Or is there another method i should consider or perhaps a combination?
I'm really interested in a concrete suggestion to my particular example above. I'm novice to AOP so please be gentle.
Went with the DynamicProxy option. It was easier to use than i thought.
All it took was the using Castle.DynamicProxy; reference...
A bit of IInterceptor...
public class PostRepoInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
invocation.Proceed();
if (invocation.Method.Name.Equals("GetAll", StringComparison.InvariantCultureIgnoreCase))
invocation.ReturnValue = this.GetModifiedGetAllResult(invocation.ReturnValue);
}
private object GetModifiedGetAllResult(object getAllResult)
{
return Post.GetOrderedPosts((IList<Post>)getAllResult);
}
}
Two new lines in StructureMap config:
public RepoRegistry()
{
var pg = new ProxyGenerator();
For<IPostRepository>()
.EnrichAllWith(z => pg.CreateInterfaceProxyWithTarget<IPostRepository>(z, new PostRepoInterceptor()));
}
..and it's done. GetAll() now behaves how i want. I can still use the interfaces the way i'm familar and i've kept it all DRY and decoupled for DDD.
Thanks to Sam and Andre.
AFAIK, StructureMap only intercepts object construction, so using it it's not going to work.
I don't know Castle, but I think that the idea - here - is to apply Decorator pattern, so you could also do it by yourself without recurring to a third party library by following the steps described in the previous link.
That's how I'd do it, since I'm not a big fan of AOP.
HTH
No, it can not change the return value. However, you can access the target inside aspect to change target's property. Assuming you has already Repository defined, here is the code to add post processing aspect to change target property.
IRepository<decimal> Rep = new Repository();
IRepository<decimal> tpRep = (IRepository<decimal>)ObjectProxyFactory.CreateProxy(Rep,
new String[] { "GetAll" },
null,
new Decoration((x, y) =>
{
Console.WriteLine("Entering " + x.GetType().ToString());
if (x.GetType().ToString() == "ThirdPartyHR.Repository")
{
List<decimal> decimals = ((Repository)x).RepList;
IEnumerable<decimal> query = decimals.OrderByDescending(num => num, new SpecialComparer()).ToList<decimal>();
((Repository)x).RepList = (List<decimal>)query;
}
}, null));
tpRep.GetAll();
List<decimal> lstRep = Rep.RepList;
If needed, I can send you complete working code. And, if possible, please reply to me from the article "Add Aspects to Object Using Dynamic Decorator" since I don't automatically get the message here.
There is an article Add Aspects to Object Using Dynamic Decorator.
It describes an approach to adding aspects to object at runtime instead of adding aspects to class at design time. Looks like that is what you want.

Unity IoC and registering primitive types

Right then, I've run into a situation using Unity that I don't know how to solve/approach...Here's my problem.
I'm developing a WPF application and I'm using MVVM (Prism Implimentation hence the Unity container). I have a ViewModel called MenuItemsViewModel (plural) which contains an IEnumerable of MenuItemViewModel (singular). In the constructor of the MenuItemsViewModel I'm populating this collection from a generator function like this...
yield return new MenuItemViewModel(eventAggregator)
{
Text = "Dashboard",
CommandText = "DASHBOARD"
};
yield return new MenuItemViewModel(eventAggregator)
{
Text = "Areas",
CommandText = "AREAS"
};
yield return new MenuItemViewModel(eventAggregator)
{
Text = "Users",
CommandText = "USERS"
}; //etc....
I don't really want to be doing this but rather relying on the container to construct these objects for me but how in Gods name do I go about that? I don't really want my Items ViewModel to have any knowledge of my Item ViewModel other than the interface it implements but I've got about 15 of these menu items, each with different property values.
I'm not completely new to DI/IoC but this is a big question for me. I see and have benefited from having my services injected but what do you do about concrete values?
Am I think totally in the wrong terms here? Should I be just resolving the concrete instance from the container and then setting the properties? That would be an option but I like my props to be readonly if possible.
I hope this is clear enough,..shout at me if not :-)
Any help is much appreciated.
I would use resolved arrays to inject menu items:
container
.RegisterInstance("DASHBOARD", new MenuItemViewModel(...))
.RegisterInstance("AREAS", new MenuItemViewModel(...))
.RegisterType<MenuItemsViewModel>(
new InjectionConstructor(new ResolvedArrayParameter<MenuItemViewModel>()))

Resources