My ultimate reason of doing what I do is to provide some caching capabilities to the DbContext. In order to achieve this, I'm trying to extend default DbSet functionality by overriding Set<T>() method in the context, and returning object of type that is directly derived from general DbSet class. Like this:
public class Context : DbContext
{
...
public override DbSet<TEntity> Set<TEntity>()
{
//var set = base.Set<TEntity>();
var set = new XxSet<TEntity>();
return set;
}
}
class XxSet<TEntity> : System.Data.Entity.DbSet<TEntity>
where TEntity : class
{
public override TEntity Find(params object[] keyValues)
{
return base.Find(keyValues);
}
}
Looks clear and simple, but when I run my tests on this, EF gives me an error:
The member 'IQueryable.Provider' has not been implemented on type
'XxSetˊ1' which inherits from 'DbSetˊ1'. Test doubles for 'DbSetˊ1'
must provide implementations of methods and properties that are used.
It asks me to implement IQueryable interface. That's I see, but why? Shouldn't it already be implemented in the base class?
I guess it must, otherwise, how would work the base functionality of Set<T>() method, which is returning object instantiated by System.Data.Entity.DbSet<TEntity> type.
Am I missing something here?
BTW. I know about Microsoft example of creating in-memory DbSets. I just want to understand why can't I do this simple way.
I don't know why it dosen't work, this looks like something that could have been done but entity dosen't like it, in this link :
NSubstitute DbSet / IQueryable<T>
there are similar errors, sorry if it dosen't help you at all –
It was the answer then ? Glad it helped you.
I've had some of these issues with classes implementing interfaces inheriting IDbSet. It's because all (or at least most of) the IQueryable methods are not implemented in the DbSet, but are extension Methods of the Queryable class. Most mocking frameworks cannot mock static extension methods. I overcame the problem by adding the method to my derived interface and implemented the methods in my class : IDerivedDbSet as per these examples:
public IQueryable<T> Where(Expression<Func<T, bool>> predicate)
{
return this._dbSet.Where(predicate);
}
public bool Any(Expression<Func<T, bool>> predicate)
{
return this._dbSet.Any(predicate);
}
Testing where these methods are used is a bit dirty though, because you now have to mock the method instead of relying on the extension actually executing on an IQueryable injected by a mock. Here's an example:
this._context = Substitute.For<IDerivedContext>();
this._permissionSet = Substitute.For<IDerivedSet<Permission>> ();
this._permission1 = new Permission
{
UserID = 1,
MenuID = 26,
PermissionAllow = true
};
var queryable = (new List<Permission> { this._permissionLink1 }).AsQueryable();
this._permissionSet.Any(Arg.Any<Expression<Func<Permission, bool>>>()).Returns(x => queryable.Any((Expression<Func<Permission, bool>>)x[0]));
var result = this._permissionsProvider.HasPermissionToSomething(this._context, 1);
Assert.IsTrue(result);
The dirty bit is that the expression parameter for the IDerivedDbSet.Any method is then used as the expression parameter for the Queryable.Any extension method invoked on queryable directly. It's not great, because it assumes that the two Any methods do the same thing, but it does allow me mock the actual query implemented and assert that the tested class is returning the correct result on that basis. If I change the query in the tested class method, the test fails.
Related
I created an Generic dropdown list to use in my controller:
GenericDropDownList("myDropDown");
private void GenericDropDownList(string dropdownName, object selectedDepartment = null) {
var dropdownQuery = unitOfWork.SalesRepository.Get(orderBy: q => q.OrderBy(d => d.FirstName));
ViewData[dropdownName] = new SelectList(dropdownQuery, "LastName", "LastName", selectedDepartment);
}
This seems to work fine. What I'm trying is to make the unitOfWork.TestRepository dynamic, so that I can use every available repository in the function:
GenericDropDownList("myDropDown", SalesRepository);
private void GenericDropDownList(string dropdownName, object repository, object selectedDepartment = null) {
var dropdownQuery = repository.Get(orderBy: q => q.OrderBy(d => d.FirstName));
ViewData[dropdownName] = new SelectList(dropdownQuery, "LastName", "LastName", selectedDepartment);
}
The above doesn't work. I get the following error:
Error CS1061 'object' does not contain a definition for 'Get' and no
extension method 'Get' accepting a first argument of type 'object'
could be found
Is it possible to make the dropdown as dynamic as I want?
The class object does not have a .Get method so it makes sense that this does not compile.
Using dynamic will fix that because then .Get is resolved at runtime, albeit at a performance cost, and with risk of a runtime error if .Get does not exist at runtime.
The best approach in my opinion is to use an interface:
private void GenericDropDownList(string dropdownName, IRepository repository, object selectedDepartment = null)
{
// ...
}
When using Entity Framework you can impose this interface on the Repository classes by using partial classes:
public partial class ThisRepository : IRepository
{
}
public partial class ThatRepository : IRepository
{
}
A catch will be that an interface can not define a property such as FirstName, so you either have to define a method for that, or use a Func<IRepository, string> for the sorting bit.
If you want a dynamic object use the dynamic type.
Or try casting it to an appropriate type:
(repository as type).Get(...)
The correct approach would be to have all your repositories implement a common interface with common methods.
For example, you can create the interface IRepository, or IRepository<TSource> if you want it to be a little more specific.
The problem is that TSource should have a FirstName property according to your expected code.
Are you sure that all repositories will have entities with FirstName property?
If the answer is no, then you cannot create such generic method (You'd need to redefine your logic, or create a specific interface that will have entities with this property, but you won't be able to pass in any repository, only the ones that implement this interface).
If the answer is yes, then you can create a base class for all your source entities (BaseEntity, for instance), which would have the FirstName property.
Supposing the answer was yes, then you can change your method's signature to:
private void GenericDropDownList(string dropdownName, IRepository<TSource> repository, object selectedDepartment = null) where TSource : BaseEntity
You would then be able to call it:
GenericDropDownList("myDropDown", SalesRepository); //SalesRepository should implement IRepository<Sale>, where Sale : BaseEntity
This question already has answers here:
Partial type inference
(3 answers)
Closed 8 years ago.
I've created the following extension method:
public static T Map<TEntity,T>(this TEntity entity) where TEntity : IEntity
{
return Mapper.Map<TEntity, T>(entity);
}
This allows the following:
Db.ExchangeSets.FirstOrDefault().Map<ExchangeSet, ExchangeSetSimpleViewModel>()
However i'm wondering if there is anyway I can modify the extension method so i can call a shorted version as follows:
Db.ExchangeSets.FirstOrDefault().Map<ExchangeSetSimpleViewModel>()
Please Note:
Whether or not automapper should be used like this is not in the scope of the question, it's more a fact finding mission.
Update
For those of you playing at home, with the help of Scott's comment I managed to find an additional solution for the above function at Generic extension method for automapper.
public static T Map<T>(this IEntity entity)
{
return (T)Mapper.Map(entity, entity.GetType(), typeof(T));
}
In case you are wondering why this is just not possible, I'd think the problem lies with ambiguity:
public static T Map<TEntity,T>(this TEntity entity) where TEntity : IEntity
{
return Mapper.Map<TEntity, T>(entity);
}
public static T Map<T>(this ExchangeSet set)
{
// ...
}
So, which method gets called? Keep in mind this is just a simple example. It's very well possible that there could be a future implementation of partial type inference, but I'd imagine it would be too confusing when it comes to overload resolution and the cost/benefit would be completely out of control. Then again, that's just speculation.
What you're asking for is not possible. When you call a generic method, either all generic type parameters must be inferable from the input or you must specify them all explicitly. Your method only has one input so you can't possibly infer two generic type parameters, thus they must always both be specified explicitly. Your suggested code implies that the method has only one generic type parameter, which would make it a different method.
If you introduce a second (chained) function call, you can achieve this:
Db.ExchangeSets.FirstOrDefault().Map().To<ExchangeSetSimpleViewModel>()
Inferred generic parameters is an all-or-nothing deal; if there aren't enough "actual" parameters passed into the method for the compiler to figure out the all of generic parameters, the compiler forces you to specify each generic parameters manually.
To be able to use the above snippet, you need to have one method call with one (the only) generic parameter inferred, and one method call with one manually specified generic parameter.
The To<> method can be implemented like this:
public static MapExtensionHelper<TEntity> Map<TEntity>(this TEntity entity) where TEntity : IEntity
{
return new MapExtensionHelper<TEntity>(entity);
}
public class MapExtensionHelper<TEntity> where TEntity : IEntity
{
public MapExtensionHelper(TEntity entity)
{
_entity = entity;
}
private readonly TEntity _entity;
public T To<T>()
{
return Mapper.Map<TEntity, T>(_entity);
}
}
I'm playing around with Domain Driven Development. I'm using a generic repository implementation that is defined as follows: (this is implemented as Repository<T>)
public interface IRepository<T> where T : class, IEventSource, new()
{
T FindByKey(Guid key);
IEnumerable<T> FindByQuery(Predicate<T> filter);
IEnumerable<T> GetAll();
T CreateObject();
}
Let's say I have an Order class, that cannot be created without a Customer parameter. I'm using CreateObject to set the Key of the entity with a sequential Guid generator.
What is the solution that minimizes development time and coupling?
Currently I have a parameterless constructor, and am calling some
Initialize(Customer) method.
I could create a ICustomerRepository, but that would mean there is a
lot of extra development time per entity.
I can also modify CreateObject to take params object[] args, but that is not type safe at compile time.
I could remove CreateObject and use constructors to create the object, but that means I need to have access to the the Guid generation algorithm everywhere I instantiate an object, increasing coupling.
In a base class for an entity I could set the key in the constructor, reducing coupling, but requiring some static reference to the algorithm.
Update
I've implemented the strategy following sll's answer. The new signature for the repository is now:
public interface IRepository<T> where T : class, IEventSource
{
T FindByKey(Guid key);
IEnumerable<T> FindByQuery(Func<T, bool> predicate);
IEnumerable<T> GetAll();
T CreateObject();
T CreateObject(IConstructorParameters parameters);
}
The parameterless CreateObject creates an instance by attempting to call the parameterless constructor (using IL Emit for performance).
The second CreateObject attempts to create a method that calls the constructor where the properties on the IConstructorParameters match a constructor on the Entity object.
Implementation:
private Dictionary<Type, Func<IConstructorParameters, T>> _constructionMethods
= new Dictionary<Type, Func<IConstructorParameters, T>>();
public T CreateObject(IConstructorParameters args)
{
T newObject;
if (args == null)
{
args = ConstructorParameters.Empty;
}
Type paramType = args.GetType();
Func<IConstructorParameters, T> constructor;
if (!_constructionMethods.TryGetValue(paramType, out constructor))
{
//Emit IL to create a Func<IConstructorParameters,T>
constructor = CreateConstructor(paramType);
_constructionMethods.Add(paramType, constructor);
}
newObject = constructor(args);
newObject.Key = _guidCreator.Generate();
return newObject;
}
Some points as suggestion, i would do as follows.
Keep IRepository generic, and also create specific interfaces containing the contract only with what is relevant to the entity, ICustomerRepository as your example.
Remove the guid generation to a service class, since this task is most relevant for the infrastructure and not domain.
If you do not want implement IOrderRepository - you can abstract CreateObject() method parameters by an interface like IConstructionParameters and then for each entity implement concrete parameters like OrderConstructionParameters.
This approach also known as Parameter Object design pattern which design rationale - more decoupled system design.
public interface IRepository<T>
{
T CreateObject(IConstructionParameters parameters);
}
public sealed class OrderConstructionParameters : IConstructionParameters
{
public Customer Customer
{
get;
private set;
}
}
So, I'm making a generic provider for my repositories implementation which will be used by my BaseController (ASP.NET MVC 2) for low-level objects. These objects have common operations, such as Activate/Deactivate/Delete/Edit, so I'll always be working with the same property on each. The problem is, since I don't know what T is, I obviously don't have access to its properties.
So, my question is, can someone show me how to get the properties I need out of the objects. I've seen some people talking about Reflection, others Expression Trees, neither of which I know how to use.
I do have a generic repository which I believe uses Expression Trees (copied it from some website), but again, I don't know what I'm doing with it... If it helps, here's what I've got so far:
public class Provider<T> where T : class {
private readonly Repository<T> Repository = null;
public Provider(
Repository<T> Repository) {
this.Repository = Repository;
}
public void Activate(
int Id) {
T Entity = this.Repository.Select(Id);
// Need to get the property here, change it and move on...
this.Repository.Submit();
}
}
I'd appreciate any help on this.
If those classes have common operations, sounds like they should inherit from the same base or implement the same interface, correct? If so, use that interface/base as the constraint for T
public class Provider<T> where T : ICommonInterface
You will then have compile-time access to the shared members provided by the interface or base class.
You could make an action
public void Activate(int Id, Action<T> doSomething)
{
T Entity = this._repository.Select(Id);
// Need to get the property here, change it and move on...
doSomething(Entity);
_repository.Submit();
}
Then using the Action delegate (in this example via a lambda) the properties will be known when activate is called:
prov.Activate(5, x => x.Address = "fgfgf");
The best solution will be to give the objects a common base type, and constrain the type parameter T to be of that type. Then you'll have access to the methods or properties of the common base type at compile time:
public class Provider<T> where T : ICommon
{
...
}
or
public class Provider<T> where T : CommonBase
{
...
}
If that's not possible, then without a common base type the best you can do is reflect upon the objects to look for and invoke the property that you are interested in:
public void Activate(int Id)
{
T entity = this.Repository.Select(Id);
// Interrogate the type of the entity and get the property called "MyPropertyName"
PropertyInfo pi = entity.GetType().GetProperty("MyPropertyName");
// Invoke the property against the entity instance - this retrieves the
// value of the property.
var value = (YourType)(pi.GetValue(entity, null));
// Do somethign with the value...
this.Repository.Submit();
}
I should add that reflection is comparatively expensive and you also lose the compile time verification. But it's handy in cases like these.
You can get a MethodInfo object for working with methods by calling:
MethodInfo mi = entity.GetType().GetMethod("MyMethodName");
I am attempting to use the Microsoft enterprise Validation methods to perform validation in my entities. In my base class I have the following method:
public class BaseEntity
{
public bool IsValid()
{
return Validate().IsValid;
}
public ValidationResults Validate()
{
return Validation.Validate<this.GetType()>(this);
}
The problem with this is that even when a subclass of BaseEntity calls IsValid, this.GetType() always returns BaseEntity, not the Subclass's type. I don't want to have to rewrite this code for every entity, as that seems very un-OO like. Is there any other way to do this?
I did have the idea to have a protected variable protected Type _validationType, and in every entity set it to that entity's .GetType value, but it seems like there has to be a better way to do this.
Update
Nevermind apparently. this.GetType() seems to be working as I was hoping. Not sure why it wasn't before.
I also changed my Validate() method to use the following code:
return ValidationFactory.CreateValidator(this.GetType()).Validate(this);
When you use an O/RM mapper such as LINQ to SQL, NHibernate or LINQ to Entities (ADO.NET Entity Framework) I'd go with another approach of validating. I'd keep the entities completely clean of validation (so no BaseEntity.Validate() in there. You can move this validation logic to the ObjectContext (EF) / DataContext (L2S) / Session (NH) and trigger validation during a database submit. Look at the example below for LINQ to SQL:
public partial class NorthwindDataContext
{
public override void SubmitChanges(ConflictMode failureMode)
{
var invalidResults = (
from entity in this.GetChangedEntities()
let type = entity.GetType()
let validator = ValidationFactory.CreateValidator(type)
let results = validator.Validate(entity)
where !results.IsValid
from result in results
select result).ToArray();
if (invalidResults.Length > 0)
{
// You should define this exception type
throw new ValidationException(invalidResults);
}
base.SubmitChanges(failureMode);
}
private IEnumerable<object> GetChangedEntities()
{
ChangeSet changes = this.GetChangeSet();
return changes.Inserts.Concat(changes.Updates);
}
}
In the case your entities are invalid, an ValidationException will be thrown. You can catch that specific exception and iterate the InvalidResults property that you'd define on it.
When you need more information, I advise you to read this article. It also describes how to do this with Entity Framework.
Good luck.
Its very un-OO like for the base class to know anything about the subclasses. This works the way it should work.
If you want to know something about the subclasses, then you need to override this method.
Apart from all that stuff about validation, there's a way to code a baseclass' method to let it know which actual subclass type it is called on.
Well... a way to pretend, at least (without breaking any OO rule, Gabriel). It is very elegant and works perfectly well :
public ValidationResults Validate<TEntity>(this TEntity e) where TEntity : BaseEntity
{
return Validation.Validate<TEntity>(e);
}
A great benefit of the extension method among others... :)
You can make IsValid() and Validate() a virtual method to provide some custom definitions in sub classes.
Moving the type logic out of BaseEntity is cleaner.
public class BaseEntity
{
public bool IsValid()
{
return Validate().IsValid;
}
public ValidationResults Validate()
{
return Validation.Validate(this);
}
}
public class Validation
{
public static ValidatorResults Validator<T>( T entity )
where T : BaseEntity
{
return ValidationFactory.CreateValidator(entity.GetType()).Validate(entity);
}
}