using System;
using System.Linq;
using System.Reflection;
using Umbraco.Core.ObjectResolution;
using Umbraco.Core.Persistence.Repositories;
using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Persistence
{
///
/// A resolver used to return the current implementation of the RepositoryInstanceFactory
///
internal class RepositoryResolver : SingleObjectResolverBase
{
internal RepositoryResolver(RepositoryFactory registrar)
: base(registrar)
{
}
///
/// Can be used by developers at runtime to set their own RepositoryInstanceFactory at app startup
///
///
public void SetRepositoryInstanceFactory(RepositoryFactory factory)
{
Value = factory;
}
///
/// Returns the RepositoryInstanceFactory object
///
internal RepositoryFactory Factory
{
get { return Value; }
}
///
/// Return the repository based on the type
///
///
///
///
internal TRepository ResolveByType(IUnitOfWork unitOfWork)
where TRepository : class, IRepository
{
var createMethod = this.Value.GetType().GetMethods(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public)
.First(x => x.Name == "Create" + typeof (TRepository).Name.Substring(1));
if (createMethod.GetParameters().Count() != 1
|| !createMethod.GetParameters().Single().ParameterType.IsType())
{
throw new FormatException("The method " + createMethod.Name + " must only contain one parameter of type " + typeof(IUnitOfWork).FullName);
}
if (!createMethod.ReturnType.IsType())
{
throw new FormatException("The method " + createMethod.Name + " must return the type " + typeof(TRepository).FullName);
}
return (TRepository) createMethod.Invoke(this.Value, new object[] {unitOfWork});
}
}
}