I'm trying to setup a base Repository class that can use the Entity Framework edmx model context. The problem I'm having is that I need to find an interface that the EF EDMX object context implements so I can pass to the constructor via dependency injections. I've got around this before by using a DataFactory that creates it and stores it in the HttpContext but that kills the ability to unit test. Any help would be appreciated. Thanks!
public abstract class BaseRepository<T> where T : EntityObject
{
private MyDataModelContext _dataContext;
private ObjectSet<T> dbset;
protected BaseRepository(IObjectContext dataContext)
{
_dataContext = dataContext;
dbset = _dataContext.CreateObjectSet<T>();
}
.....
I've always created a DataContextFactory that passes my own interface to the Context, and passed that to my repositories like so:
The context interface:
public IMyDataContext {
// One per table in the database
IDbSet<Class1> Class1s { get;set; }
// etc
// The standard methods from EF you'll use
void Add( object Entity );
void Attach( object Entity );
void Delete( object Entity );
void SaveChanges();
}
The context factory:
public class MyDataContextFactory : IMyDataContextFactory {
public IMyDataContext GetContext() {
// TODO: Use the service locator pattern to avoid the direct instanciation
return new MyDataContext();
}
}
The context factory interface:
public interface IMyDataContextFactory {
IMyDataContext GetContext();
}
The repository:
public class MyClass1Repository {
private readonly IMyDataContextFactory factory;
public MyClass1Repository( IMyDataContextFactory Factory ) {
// TODO: check for null
this.factory = Factory;
}
public List<MyClass1> GetAll() {
using ( IMyDataContext db = this.factory.GetContext() ) {
return db.Class1s.ToList();
}
}
// TODO: Other methods that get stuff
}
Then when I want to test the repository, I pass in a fake IMyDataContextFactory that returns a fake IMyDataContext from GetContext().
In time I notice duplication in repositories, and can push certain methods into the base repository: GetAll(), Save(), GetById() sometimes if I have consistent primary keys, etc.
Related
I am new to the MVVM architecture in Android, and I have some days with a doubt that I consider basic, but that I can't solve.
I proceed to discuss my problem:
I have an Entity, CustomerView (this entity is created from a DatabaseView):
#DatabaseView("select ... ")
public class CustomerView {
public String cardCode;
public String cardName;
public String cardFName;
...
Then, I have a Dao class:
#Dao
public interface OCRD_DAO {
...
#Query("SELECT * from CustomerView where cardCode= :cardCode")
LiveData<CustomerView> getCustomerViewByCardCode(String cardCode);
...
}
The repository class, makes use of the DAO class:
public LiveData<CustomerView> getCustomer(String cardCode){
return mOcrdDao.getCustomerViewByCardCode(cardCode);
}
The CustomerSheetViewModel class:
public class CustomerSheetViewModel extends BaseObservable {
private Repository mRepository;
public LiveData<CustomerView> mCustomer;
private MutableLiveData<String> _cardName;
#Bindable
public MutableLiveData<String> getCardName(){
return this._cardName;
}
public MutableLiveData<String> setCardName(String value){
// Avoids infinite loops.
if (mCustomer.getValue().cardName != value) {
mCustomer.getValue().cardName = value;
// React to the change.
saveData();
// Notify observers of a new value.
notifyPropertyChanged(BR._cardName);
}
}
public CustomerSheetViewModel (Application application, String cardCode) {
mRepository = new Repository(application);
this.mCustomer = mRepository.getCustomer(cardCode);
//Init MutableLiveData????
this._cardName = this.mCustomer.getValue().cardName;
//Null Exception, because this.mCustomer.getValue() is null
}
}
At this point, my problem occurs: when I initialise the CustomerView object, it is of type LiveData. However, if I want to make use of 2-way binding, I need an object of type MutableLiveData. So, I think I should create the MutableLiveData object with the data extracted from the database (i.e. from the call to the repository). When I try this (e.g. getValue().cardName) a null exception is thrown, since LiveData is asynchronous.
Finally, I could make use of this property in the layout:
android:text="#={customerSheetViewModel.cardName}"
I really appreciate any help, as I can't find any reference to 2-way binding when the data comes from a database read.
Thanks in advance.
I'm looking to get the Spring Data Repository interface or the bean calling void delete(id) using AspectJ, the problem with that function is there is no argument or return type to guess the bean, is there any idea how to get the calling bean or the interface name from AspectJ ProceedingJoinPoint.
this is my actual code:
#Pointcut("execution(public * org.springframework.data.repository.Repository+.save(..)) || execution(public * org.springframework.data.repository.Repository+.delete(..)) && target(repository)")
public void publicNonVoidRepositoryMethod(CrudRepository repository) {
}
#Around("publicNonVoidRepositoryMethod(CrudRepository repository)")
public Object publicNonVoidRepositoryMethod(ProceedingJoinPoint pjp , CrudRepository repository) throws Throwable {
.......
}
You can add target parameter to get your repository that has been called:
#Aspect
#Component
public class SampleAspect {
// Apply to all repositories in package repositories
#After("execution(* repositories.*.delete(*)) && target(repository) && args(id)")
public void afterEntityDelete(CrudRepository repository, Object id) {
...
}
}
This is an old question but someone might find this helpful.
Declare pointcut for all delete methods on CrudRepository, PagingAndSortingRepository etc..:
When called from your code, you may pass on the entity itself
On the other hand, when invoked via Spring Data REST, the delete method is invoked with ID (Long in this example)
I'm using reflection to get to the bottom of the entity type in the latter scenario. Note: all my entities are implementing Identifiable interface to allow easy access to getId():
#Pointcut("execution(* org.springframework.data.repository.*.delete(..)) && args(entity)")
public void repoDelete(Object entity) {}
#Around(value="repoDelete(entity)",argNames="entity")
public void onDelete(ProceedingJoinPoint pjp, Object entity) throws Throwable{
String invoker = null; //this will become the type name
Long entityId = 0L;
if (entity.getClass().getName().equals("java.lang.Long")){
entityId = (Long)entity;
REFLECT: {
// this returns a list of JPA repository-related interfaces
Class[] interfaces = jp.getTarget().getClass().getInterfaces();
for (Class iface: interfaces) {
// one of them is your JPA repository
if (iface.getName().startsWith("YOUR REPO PACKAGE")){
// the entity type can be accessed via generics
ParameterizedType pType = (ParameterizedType) iface.getGenericInterfaces()[0];
// this list contains two values - the entity type and the identifier type
Type[] typeArgs = pType.getActualTypeArguments();
for (Type t: typeArgs) {
if (t.getTypeName().startsWith("YOUR ENTITY PACKAGE")) {
invoker = t.getTypeName();
break REFLECT;
}
}
}
}
}
} else {
invoker = entity.getClass().getName();
if (entity instanceof Identifiable) entityId = (Long) ((Identifiable) entity).getId();
}
// do whatever you need ...
pjp.proceed();
}
I am trying to understand the delegate factory pattern with Autofac. I know how to implement factory using IIndex<> with Keyed() registration, which is explained nicely in here: Configuring an Autofac delegate factory that's defined on an abstract class
I would like to know if I can create a factory using Func<>, and how would I do the registrations for the following sample:
public enum Service
{
Foo,
Bar
}
public interface FooService : IService
{
ServiceMethod();
}
public interface BarService : IService
{
ServiceMethod();
}
public class FooBarClient
{
private readonly IService service;
public FooBarClient(Func<Service, IService> service)
{
this.service = service(Service.Foo);
}
public void Process()
{
service.ServiceMethod(); // call the foo service.
}
}
Autofac cannot construct this Func<Service, IService> for you which lets you return different types based on a parameter. This is what IIndex<> is for.
However if you don't want/cannot use IIndex<> you can create this factory function with the help of the Keyed or Named and register your factory in the container:
var builder = new ContainerBuilder();
builder.RegisterType<FooBarClient>().AsSelf();
builder.RegisterType<FooService>().Keyed<IService>(Service.Foo);
builder.RegisterType<BarService>().Keyed<IService>(Service.Bar);
builder.Register<Func<Service, IService>>(c =>
{
var context = c.Resolve<IComponentContext>();
return s => context.ResolveKeyed<IService>(s);
});
I have read as many of the posts on Stackoverflow as I can find with regards the use of a Unit of Work pattern within
an ASP.Net MVC 3 application which includes a Business Layer. However, I still have a couple of questions with
regards this topic and would greatly appreciate any feedback people can give me.
I am developing an ASP.Net MVC 3 Web application which uses EF 4.1. I will be using both the Repository and
Unit of Work Patterns with this project similar to how they are used in this great tutorial
The difference in my project is that I need to also include a Business Layer (separate project in my solution) in order to
carry out the various business rules for the application. The tutorial mentioned above does not have a Business layer, and
therefore creates an instance of the Unit of Work class from the controller
public class CourseController : Controller
{
private UnitOfWork unitOfWork = new UnitOfWork();
However, my question is, where should I create the instance of the Unit of Work class if I have a Business Layer?
I personally think it should be created in my controller and then injected into the Business Layer like so:
public class PeopleController : Controller
{
private readonly IUnitOfWork _UoW;
private IPersonService _personService;
public PeopleController()
{
_UoW = new UnitOfWork();
_personService = new PersonService(_UoW);
}
public PeopleController(IUnitOfWork UoW, IPersonService personService)
{
_UoW = UoW;
_personService = personService;
}
public ActionResult Edit(int id)
{
Person person = _personService.Edit(id);
return View(person);
}
public class UnitOfWork : IUnitOfWork, IDisposable
{
private BlogEntities _context = new BlogEntities();
private PersonRepository personRepository = null;
public IPersonRepository PersonRepository
{
get
{
if (this.personRepository == null)
{
this.personRepository = new PersonRepository(_context);
}
return personRepository;
}
}
public void Save()
{
_context.SaveChanges();
}
public class PersonService : IPersonService
{
private readonly IUnitOfWork _UoW;
public PersonService(IUnitOfWork UoW)
{
_UoW = UoW;
}
public Person Edit(int id)
{
Person person = _UoW.PersonRepository.GetPersonByID(id);
return person;
}
public class PersonRepository : IPersonRepository
{
private readonly BlogEntities _context;
public PersonRepository(BlogEntities context)
{
_context = context;
}
public Person GetPersonByID(int ID)
{
return _context.People.Where(p => p.ID == ID).Single();
}
I have read others saying that the Unit of Work instantiation should not be in the Controller, but created in the Service Layer
instead. The reason why I am not so sure about this approach is because my Controller may have to use several different
Service Layers in one business transaction, and if the Unit of Work instance was created inside each Service, it would result in several
Unit of Work instances being created, which defeats the purpose, ie, one Unit of Work per business transaction.
Maybe what I have explained above is wrong, but if so, I would greatly appreciate if someone could put me right.
Thanks again for your help.
I think you have a couple of changes to make:.
Allow your DI container to inject a UnitOfWork instance into your Service classes in their constructors, and leave it out of your Controller altogether.
If your DI container supports it (Ninject does, for example), configure your UnitOfWork to be managed on a per-request basis; this way your services will be handed a distinct UnitOfWork for each request, and you're all done. Or...
If your DI container does not support per-request lifetimes, configure it to manage the UnitOfWork as a singleton, so every Service class gets the same instance. Then update your UnitOfWork to store its Entities object in a data store which stores objects on a per-request basis, for example in HttpContext.Current.Items, as described here.
Edit 1
Regarding where the UnitOfWork should be injected; I'd say the Service layer is the correct place. If you imagine your system as a series of layers where the outer layers deal with user interactions and the lower layers deal with data storage, each layer should become less concerned with users and more concerned with data storage. UnitOfWork is a concept from one of the 'lower-level' layers and Controller is from a higher-level layer; your Service layer fits between them. It therefore makes sense to put the UnitOfWork into the Service class rather than the Controller.
Edit 2
To elaborate on the UnitOfWork creation and it's relationship to HttpContext.Current.Items:
Your UnitOfWork would no longer hold a reference to an Entities object, that would be done through the HttpContext object, injected into the UnitOfWork behind an interface like this:
public interface IPerRequestDataStore : IDisposable
{
bool Contains(string key);
void Store<T>(string key, T value);
T Get<T>(string key);
}
The HttpContext object would then implement IPerRequestDataStore like this:
public class StaticHttpContextPerRequestDataStore : IPerRequestDataStore
{
public bool Contains(string key)
{
return HttpContext.Current.Items.Contains(key);
}
public void Store<T>(string key, T value)
{
HttpContext.Current.Items[key] = value;
}
public T Get<T>(string key)
{
if (!this.Contains(key))
{
return default(T);
}
return (T)HttpContext.Current.Items[key];
}
public void Dispose()
{
var disposables = HttpContext.Current.Items.Values.OfType<IDisposable>();
foreach (var disposable in disposables)
{
disposable.Dispose();
}
}
}
As an aside, I've called it StaticHttpContextPerRequestDataStore as it uses the static HttpContext.Current property; that's not ideal for unit testing (another topic altogether), but at least the name indicates the nature of its dependency.
Your UnitOfWork then passes the IPerRequestDataStore it's given to each of its Repository objects so they can access the Entities; this means that no matter how many UnitOfWork instances you create, you'll use the same Entities object throughout a request because it's stored and retrieved in the IPerRequestDataStore.
You'd have an abstract base Repository which would use its IPerRequestDataStore to lazy-load its Entities object like this:
public abstract class RepositoryBase : IDisposable
{
private readonly IPerRequestDataStore _dataStore;
private PersonRepository personRepository;
protected RepositoryBase(IPerRequestDataStore dataStore)
{
this._dataStore = dataStore;
}
protected BlogEntities Context
{
get
{
const string contextKey = "context";
if (!this._dataStore.Contains(contextKey))
{
this._dataStore.Store(contextKey, new BlogEntities());
}
return this._dataStore.Get<BlogEntities>(contextKey);
}
}
public void Dispose()
{
this._dataStore.Dispose();
}
}
Your PeopleRepository (for example) would look like this:
public class PeopleRepository : RepositoryBase, IPersonRepository
{
public PeopleRepository(IPerRequestDataStore dataStore)
: base(dataStore)
{
}
public Person FindById(int personId)
{
return this.Context.Persons.FirstOrDefault(p => p.PersonId == personId);
}
}
And finally, here's the creation of your PeopleController:
IPerRequestDataStore dataStore = new StaticHttpContextDataStore();
UnitOfWork unitOfWork = new UnitOfWork(dataStore);
PeopleService service = new PeopleService(unitOfWork);
PeopleController controller = new PeopleController(service);
One of the central concepts here is that objects have their dependencies injected into them via their constructors; this is generally accepted as good practice, and more easily allows you to compose objects from other objects.
I have a repository pattern i created on top of the ado.net entity framework. When i tried to implement StructureMap to decouple my objects, i kept getting StackOverflowException (infinite loop?). Here is what the pattern looks like:
IEntityRepository where TEntity : class
Defines basic CRUD members
MyEntityRepository : IEntityRepository
Implements CRUD members
IEntityService where TEntity : class
Defines CRUD members which return common types for each member.
MyEntityService : IEntityService
Uses the repository to retrieve data and return a common type as a result (IList, bool and etc)
The problem appears to be with my Service layer. More specifically with the constructors.
public PostService(IValidationDictionary validationDictionary)
: this(validationDictionary, new PostRepository())
{ }
public PostService(IValidationDictionary validationDictionary, IEntityRepository<Post> repository)
{
_validationDictionary = validationDictionary;
_repository = repository;
}
From the controller, i pass an object that implements IValidationDictionary. And i am explicitly calling the second constructor to initialize the repository.
This is what the controller constructors look like (the first one creates an instance of the validation object):
public PostController()
{
_service = new PostService(new ModelStateWrapper(this.ModelState));
}
public PostController(IEntityService<Post> service)
{
_service = service;
}
Everything works if i don't pass my IValidationDictionary object reference, in which case the first controller constructor would be removed and the service object would only have one constructor which accepts the repository interface as the parameter.
I appreciate any help with this :) Thanks.
It looks like the circular reference had to do with the fact that the service layer was dependent on the Controller's ModelState and the Controller dependent on the Service layer.
I had to rewrite my validation layer to get this to work. Here is what i did.
Define generic validator interface like below:
public interface IValidator<TEntity>
{
ValidationState Validate(TEntity entity);
}
We want to be able to return an instance of ValidationState which, obviously, defines the state of validation.
public class ValidationState
{
private readonly ValidationErrorCollection _errors;
public ValidationErrorCollection Errors
{
get
{
return _errors;
}
}
public bool IsValid
{
get
{
return Errors.Count == 0;
}
}
public ValidationState()
{
_errors = new ValidationErrorCollection();
}
}
Notice that we have an strongly typed error collection which we need to define as well. The collection is going to consist of ValidationError objects containing the property name of the entity we're validating and the error message associated with it. This just follows the standard ModelState interface.
public class ValidationErrorCollection : Collection<ValidationError>
{
public void Add(string property, string message)
{
Add(new ValidationError(property, message));
}
}
And here is what the ValidationError looks like:
public class ValidationError
{
private string _property;
private string _message;
public string Property
{
get
{
return _property;
}
private set
{
_property = value;
}
}
public string Message
{
get
{
return _message;
}
private set
{
_message = value;
}
}
public ValidationError(string property, string message)
{
Property = property;
Message = message;
}
}
The rest of this is StructureMap magic. We need to create validation service layer which will locate validation objects and validate our entity. I'd like to define an interface for this, since i want anyone using validation service to be completely unaware of the StructureMap presence. Besides, i think sprinkling ObjectFactory.GetInstance() anywhere besides the bootstrapper logic a bad idea. Keeping it centralized is a good way to insure good maintainability. Anyway, i use the decorator pattern here:
public interface IValidationService
{
ValidationState Validate<TEntity>(TEntity entity);
}
And we finally implement it:
public class ValidationService : IValidationService
{
#region IValidationService Members
public IValidator<TEntity> GetValidatorFor<TEntity>(TEntity entity)
{
return ObjectFactory.GetInstance<IValidator<TEntity>>();
}
public ValidationState Validate<TEntity>(TEntity entity)
{
IValidator<TEntity> validator = GetValidatorFor(entity);
if (validator == null)
{
throw new Exception("Cannot locate validator");
}
return validator.Validate(entity);
}
#endregion
}
I'm going to be using validation service in my controller. We could move it to the service layer and have StructureMap use property injection to inject an instance of controller's ModelState to the service layer, but i don't want the service layer to be coupled with ModelState. What if we decide to use another validation technique? This is why i'd rather put it in the controller. Here is what my controller looks like:
public class PostController : Controller
{
private IEntityService<Post> _service = null;
private IValidationService _validationService = null;
public PostController(IEntityService<Post> service, IValidationService validationService)
{
_service = service;
_validationService = validationService;
}
}
Here i am injecting my service layer and validaton service instances using StructureMap. So, we need to register both in StructureMap registry:
ForRequestedType<IValidationService>()
.TheDefaultIsConcreteType<ValidationService>();
ForRequestedType<IValidator<Post>>()
.TheDefaultIsConcreteType<PostValidator>();
That's it. I don't show how i implement my PostValidator, but it's simply implementing IValidator interface and defining validation logic in the Validate() method. All that's left to do is call your validation service instance to retrieve the validator, call the validate method on your entity and write any errors to ModelState.
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create([Bind(Exclude = "PostId")] Post post)
{
ValidationState vst = _validationService.Validate<Post>(post);
if (!vst.IsValid)
{
foreach (ValidationError error in vst.Errors)
{
this.ModelState.AddModelError(error.Property, error.Message);
}
return View(post);
}
...
}
Hope i helped somebody out with this :)
I used a similar solution involving a generic implementor of IValidationDictionary uses a StringDictionary and then copied the errors from this back into the model state in the controller.
Interface for validationdictionary
public interface IValidationDictionary
{
bool IsValid{get;}
void AddError(string Key, string errorMessage);
StringDictionary errors { get; }
}
Implementation of validation dictionary with no reference to model state or anything else so structuremap can create it easily
public class ValidationDictionary : IValidationDictionary
{
private StringDictionary _errors = new StringDictionary();
#region IValidationDictionary Members
public void AddError(string key, string errorMessage)
{
_errors.Add(key, errorMessage);
}
public bool IsValid
{
get { return (_errors.Count == 0); }
}
public StringDictionary errors
{
get { return _errors; }
}
#endregion
}
Code in the controller to copy the errors from the dictionary into the model state. This would probably be best as an extension function of Controller.
protected void copyValidationDictionaryToModelState()
{
// this copies the errors into viewstate
foreach (DictionaryEntry error in _service.validationdictionary.errors)
{
ModelState.AddModelError((string)error.Key, (string)error.Value);
}
}
thus bootstrapping code is like this
public static void BootstrapStructureMap()
{
// Initialize the static ObjectFactory container
ObjectFactory.Initialize(x =>
{
x.For<IContactRepository>().Use<EntityContactManagerRepository>();
x.For<IValidationDictionary>().Use<ValidationDictionary>();
x.For<IContactManagerService>().Use<ContactManagerService>();
});
}
and code to create controllers is like this
public class IocControllerFactory : DefaultControllerFactory
{
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
return (Controller)ObjectFactory.GetInstance(controllerType);
}
}
Just a quick query on this. It's helped me out quite a lot so thanks for putting the answer up, but I wondered which namespace TEntity exists in? I see Colletion(TEntity) needs System.Collections.ObjectModel. My file compiles without anything further but I see your TEntity reference highlighted in Blue which suggests it has a class type, mine is Black in Visual Studio. Hope you can help. I'm pretty keen to get this working.
Have you found any way to seperate validation into the service layer at all? My gut tells me that validating in the Controller is a bit smelly but I've looked high and low to find a way to pass validation error messages back to the controller without tightly coupling the service layer to the controller and can't find anything. :(
Again, thanks for the great post!
Lloyd