I am writing a new database provider for Entity Framework Core 1.1.2 (with target framework: .NET 4.5.2), and I have a very frustrating issue. My relevant installed NuGet packages are:
Microsoft.EntityFrameworkCore
Microsoft.EntityFrameworkCore.Relational
Microsoft.EntityFrameworkCore.SqlServer
I have a MyDbSet class which inherits from Microsoft.EntityFrameworkCore.DbSet:
public class MyDbSet<TEntity> : DbSet<TEntity> where TEntity : class {
}
I have a context class which is as simple as:
public class MyContext : DbContext {
public MyDbSet<MyOtherModel> Others { get; set; }
// Constructor
public MyModel() {
others = new MyDbSet<MyOtherModel>();
}
}
I instantiate a MyContext object,
MyContext myContext = new MyContext();
and I want to do the following:
myContext.Others.Add(new MyOtherModel());
Here I receive an exception saying that the Add method is unimplemented.
Seeing the EF Core documentations, DbSet really is an abstract class with abstract, unimplemented methods. Is it right? Should I really write my own DbSet implementation? Or is there a default implementation of it somewhere? If so, which assembly / NuGet package do I need to access this?
Related
I am using Visual Studio 2013 RTM with asp.net mvc 5 entity framework asp net identity provider
I am doing the following
public class MyContext : IdentityDbContext<MyUser>
{
public MyContext (DbCompiledModel model):base(model)
{
}
public DbSet<Foo> Foos{ get; set; }
public DbSet<Bar> Bars{ get; set; }
}
and getting a compile time error on this line
public MyContext (DbCompiledModel model):base(model)
The class IdentityDbContext has hide all the constructors of DbContext.
Are there any workaround?
IdentityDbContext has only two constructors
IdentityDbContext()
IdentityDbContext(String connectionString)
As you are inheriting the IdentityDbContext, you need to follow its available guidance. So, you cannot use DbCompiledModel to construct the context.
I using Ninject 3 in Repository pattern in mvc 3 (steven sanderson Scaffolder).
and in ninject i have the class "NinjectWebCommon" which in the "RegisterServices" method i resolved the dependencies and i think im ready to go.
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<ICityRepository>().To<CityRepository>();
kernel.Bind<IVillageRepository >().To<VillageRepository>();
}
i using my repositories in controllers using constructor injection and everything is fine.
public class CityController : Controller
{
private readonly ICityRepository cityRepository;
// If you are using Dependency Injection, you can delete the following constructor
//public CityController() : this(new CityRepository())
//{
//}
public CityController(ICityRepository cityRepository)
{
this.cityRepository = cityRepository;
}
// .........
}
but when i use this repositories in other classes like Model(Entity) classes using property injection or field injection the dependency doesn't resolved and i get null reference exception on my Property or field.
[MetadataType(typeof(CityMetadata))]
public partial class City : IValidatableObject
{
[Inject]
public IVillageRepository VillageRepo { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
var village = VillageRepo.Find(5); // will throw null reference exception on "VillageRepo"
}
}
public partial class CityMetadata
{
[ScaffoldColumn(false)]
public int ID { get; set; }
[Required(ErrorMessage = MetadataErrorMessages.Required)]
[StringLength(50, ErrorMessage = MetadataErrorMessages.ExceedMaxLength)]
public string Name { get; set; }
}
i don't know why this happening. so whats the problem and how can i use the repositories in non-controller classes?
thanks in advance.
Your problem is, you're expecting magic. You inject an implementation for your repository, and then you expect that data objects created by that repository are injected with references of the creating repository.
First of all, that doesn't work like that. The implementation of the repository will call new() (or Activator.CreateInstance) on your entities, not ask for an instance from a Ninject Kernel or Factory. You could rewrite the repository (it'll get trickier if you're using EF there...) but it's probably not worth the hassle.
On the top of it all, you shouldn't be needing that at all. Entities shouldn't depend on repositories, imho not even their interfaces.
EDIT: now I see why you want to see a repo in your model. What I recommend is a static factory maybe.
public class Factories
{
public static readonly Instance = new Factories();
[Inject]
public Func<IVillageRepository> VillageRepo {get; set;}
}
Then call Kernel.Inject(Factories.Instance); from your Ninject initialization code (where you bind IVillageRepository). Then modify your validatable implementation to Factories.Instance.VillageRepo().Find(...);
I am a newbie in TDD (Asp.net MVC3 environment) and trying to adopt TDD as our better better development approach.
In our production code,we have a following scenario
In web
//Autofac used to resolve Dependency
TestController(XService xSerivice,YSerivice yService)
{_xService =xService,_YService= yService}
[HTTPPost]
ActionResult Create(A1 a1)
{
_xService.XUnitOfWork.A1.add(a1)
_xService.XUnitOfwork.SaveChanges();
}
// where X, Y are different context,Concrete class, no interface implemented!
In Business Layer
Xservice(XUnitofWork) // no interface implemented!
In DAL Layer
'XUnitofWork:DataRepostory(Generic)...
{
GenericRepository<a1Entity> A1,
GenericRepository<a2Entity> A2
}
Now I realize that we should implement interface both in our BAL and Web layer.
My question is are there any way i can mock the services(XService,YService) in our controller to test some behavior (TDD) [for example save change exception occur while saving a entity via' _xService.XUnitOfwork.SaveChanges()'?
Please help.Thanks in Advance!
If you mark members (properties, methods) in your concrete class as virtual, I think you may be able to just mock those methods / properties individually. (I think the VB equivalent of virtual is Overridable..?)
Moq works by creating a new concrete implementation of something at runtime when your test runs. This is why it works so well with interfaces and abstract classes. But if there is no interface or abstract class, it needs to override a method or property.
Reply to question author's answer:
Since you are a self-proclaimed TDD newbie, I just wanted to point out that adding a parameterless constructor to a class just for the sake of making the class testable should not be an acceptable solution.
By giving your GenericRepository class a hard dependency on Entity Framework's DbSet / IDbSet, you are creating a tight coupling between your repository implementation and EF... note the using System.Data.Entity line at the top of that file.
Any time you decide to add a constructor dependency, you should seriously consider adding it as an interface or abstract class. If you need access to members of a library which you do not control (like EF's DbContext), follow Morten's answer and wrap the functionality in your own custom interface.
In the case of DbContext, this class does more than just provide you with a UnitOfWork implementation. It also provides you a way of querying out data and adding / replacing / removing items in your repository:
public interface IUnitOfWork
{
int SaveChanges();
}
public interface IQuery
{
IQueryable<TEntity> GetQueryable<TEntity>() where TEntity : class;
}
public interface ICommand : IQuery
{
void Add(object entity);
void Replace(object entity);
void Remove(object entity);
}
You can pretty easily wrap DbContext in these 3 interfaces like so:
public class MyCustomDbContext : DbContext, IUnitOfWork, ICommand
{
// DbContext already implements int SaveChanges()
public IQueryable<TEntity> GetQueryable<TEntity>() where TEntity : class
{
return this.Set<TEntity>();
}
public void Add(object entity)
{
this.Entry(entity).State = EntityState.Added;
}
public void Replace(object entity)
{
this.Entry(entity).State = EntityState.Modified;
}
public void Remove(object entity)
{
this.Entry(entity).State = EntityState.Deleted;
}
}
Note how your interfaces take no dependencies on System.Data.Entity. They use primitives and standard .NET types like object, IQueryable<T>, and int. This way, when you give your generic repository dependencies on the interfaces, you can remove the dependency on System.Data.Entity:
// using System.Data.Entity; // no need for this dependency any more
public class GenericRepository
{
private readonly ICommand _entities;
private readonly IQueryable<TEntity> _queryable;
public GenericRepository(ICommand entities)
{
this._entities = entities;
this._queryable = entities.GetQueryable<TEntity>();
}
//public GenericRepository()
//{
// no need for a parameterless constructor!
//}
}
...and your GenericRepository is now fully unit testable, since you can easily mock any of these interface methods.
Final Notes:
Also, after seeing your answer to your own question, it looks like you have CompanyRepository as a property of your UnitOfWork class. You then inject UnitOfWork as a dependency on your CompanyInformationController. This is backwards. Instead, you should be injecting the CompanyRepository (or its interface) into the controller's constructor. The UnitOfWork pattern has nothing to do with maintaining references for your known repositories. It is about tracking multiple changes made to related items so that they can all be pushed once as a single transaction. EF does this automatically, so as long as AutoFac is providing the same DbContext instance no matter whether your app requests an IQuery, ICommand, or IUnitOfWork implementation, then the only method UnitOfWork should be concerned with is SaveChanges().
thanks for your reply. The test I was trying to do was successful after spending few hours and changes my previous code.
Changes are follows:
1) Now using UnitofWork in my controller instead of a redundant service.
2) Added a parameter less constructor to the GenericRepository Class.(with out any DBContext!),because it will requied a DBContext as a parameter in Constructor,which can not be substituted by supplying a Mocked DBContext.
GenericRepository:
public class GenericRepository where TEntity : class
{
internal DbContext _context;
internal DbSet<TEntity> dbSet;
public GenericRepository(DbContext context)
{
this._context = context;
this.dbSet = context.Set<TEntity>();
}
public GenericRepository() //newly added!
{
}
...............
Complete Test
[TestMethod]
public void Index_Return_OneModel_WhenCalling()
{
//arrange
AutoMapperExtension automapper = new AutoMapperExtension();
var moqentities = new Mock<SetupEntities>();
List<CompanyInformation> list =new List<CompanyInformation>();
list.Add(new CompanyInformation{ CompanyName = "a", CompanyAddress = "aa", Id = 1});
list.Add(new CompanyInformation { CompanyName = "b", CompanyAddress = "b", Id = 2 });
var unitOfWork = new Mock<UnitOfWork>(moqentities.Object);
unitOfWork.Setup(d => d.CompanyRepository).Returns(new GenericRepository<CompanyInformation>());
unitOfWork.Setup(d => d.CompanyRepository.GetAll()).Returns(list.AsQueryable());
var controller = new CompanyInformationController(unitOfWork.Object);
//Act
var result =(ViewResult) controller.Index();
var model =(CompanyInformationViewModel) result.ViewData.Model;
//Assert
Assert.AreEqual(1, model.Id);
}
The best way is to create an interface for XService. If that is not possible for some reason (if XService is a third party class that doesn't implement an interface), then consider wrapping the functionality in a wrapperclass that does have an interface.
I have a MVC3 project that uses the Entity Framework and Ninject v2.2, and follows the Unit of Work pattern with a Service Layer wrapping my repositories.
After looking at the code below, hopefully its apparent that Ninject is using constructor chaining to inject the correct classes. It currently works prefectly in my application, however I am at the point that I need to bind an instance of IDatabase to MyDatabase with a different scope such as InSingletonScope() or InNamedScope(), not InRequestScope(). I know that I can use the [Named("MyDatabaseScope")] Attribute to customize which IDatabase object is injected, however it seems that with my code structure, if I wanted to inject my SingletonScoped instance, I would have to recreate a new Abstract and Concrete Implementation of my Unit of Work, my Service and all my Repositories, that will then chain down.
Basically my application currently goes
Controller -> Unit of Work -> Database, (Repositories -> Database)
If I have to change my Database Binding, I will now have to create another chain in addition to the current one:
Controller -> New Unit of Work -> SingletonDatabase, (New Repositories-> SingletonDatabase)
This seems to completely defeat the DRY principal. Is there a way to, from the Controller Constructor, inform Ninject that when doing constructor chaining it should use my singleton (or named binding) rather than my request scope binding, without having to recreate all my classes with a Named attribute, or a new Interface?
Sorry for the long text, I wasnt sure if I could get the point across without my code snippets and my somewhat rambling explaination.
Ninject Module Load Function:
..snip..
Bind<IUserServices>().To<UserServices>();
Bind<IBaseServices>().To<BaseServices>();
Bind<IUserRepository>().To<UserRepository>();
Bind(typeof (IRepository<>)).To(typeof (RepositoryBase<>));
Bind<IUnitOfWork>().To<UnitOfWork>();
Bind<IDatabase>().To<MyDatabase>().InRequestScope();
//This is my problem:
//Bind<IDatabase>().To<MySingletonDatabase>().InSingletonScope();
Unit of Work Implementation Constructor:
public class UnitOfWork : IUnitOfWork
{
private IDatabase _database;
public UnitOfWork(IDatabase database,
IUserRepository userRepository,
IPeopleRepository peopleRepository,
)
{
this._database = database;
this.UserRepository = userRepository;
this.PeopleRepository = peopleRepository;
}
protected IDatabase Database
{
get { return _database; }
}
...snip...
}
User Service Layer Implementation Constructor:
public class UserServices : BaseServices, IUserServices
{
private IUnitOfWork _uow;
public UserServices(IUnitOfWork uow)
: base(uow)
{
_uow = uow;
}
...snip...
}
User Repository Constructor:
public class UserRepository : RepositoryBase<User>, IUserRepository
{
public UserRepository(IDatabase database)
: base(database)
{
}
...snip...
}
Controller Constructor:
public IUserServices _userServices { get; set; }
public ActivityController(IUserServices userServices)
{
_userServices = userServices;
}
}
Using Ninject 3.0.0 you can use WhenAnyAncestrorNamed("Some name") But if you need to run asyncronous things you should thing about splitting your application into a web frontend and a server backend. This could make many things easier.
I am in doubt about how to use the factory in Ninject and FluentValidatior.
This article helped me a lot, but I do not understand how to use the factory to instantiate my validators:
I also found some other articles like this but with StructureMap!
Follow the steps I performed
Installed Ninject and FluentValidation via nuget
Installed Ninject.Web.Mvc.FluentValidation for factory class
And now?
When installing the Ninject, he created the NinjectMVC3.cs in App_Start folder so I set my dependencies in RegisterServices method:
kernel.Bind<IHumanValidator>().To<ReCaptchaValidate>().InRequestScope();
In Global.asax the Application_Start method:
var ninjectValidatorFactory = new NinjectValidatorFactory(new StandardKernel());
ModelValidatorProviders.Providers.Add(new FluentValidationModelValidatorProvider(ninjectValidatorFactory));
DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;
FluentValidationModelValidatorProvider.Configure();
FluentValidator I have:
public class RegisterCoupleValidator : AbstractValidator<RegisterCoupleModel>
{
public RegisterCoupleValidator()
{
RuleFor(p => p.HumanValidator).SetValidator(new HumanValidator());
}
}
HumanValidator.cs
public class HumanValidator : PropertyValidator
{
[Inject]
public IHumanValidator HumanValidate { get; set; }
public HumanValidator(IHumanValidator hValidator)
: this()
{
HumanValidate = hValidator;
}
public HumanValidator()
: base("Texto digitado está incorreto. Por favor, tente novamente.")
{ }
protected override bool IsValid(PropertyValidatorContext context)
{
return HumanValidate.IsValid();
}
}
My questions
In RegisterCoupleValidator class with the factory how do I not have instances the validators?
Specifically in new HumanValidator()
In HumanValidator class the HumanValidate property always is null, why?
Obs1: I do not want to instantiate these validators of FluentValidator, I want Ninject to resolve the dependencies for me using this factory.
Obs2: I would not have to access the Ninject kernel, since in several posts I read that this would be an anti-partner.
Have a look at this blog post. The guy is using a NuGet package to setup FluentValidation with Ninject. It is pretty simple and well explained.