Custom Logic and Proxy Classes in ADO.NET Data Services - ado.net

I've just read "Injecting Custom Logic in ADO.NET Data Services" and my next question is, How do you get your [WebGet] method to show up in the client-side proxy classes? Sure, I can call this directly (RESTfully) with, say, WebClient but I thought the strong typing features in ADO.NET Data Services would "hide" this from me auto-magically.
So here we have:
public class MyService : DataService<MyDataSource>
{
// This method is called only once to initialize service-wide policies.
public static void InitializeService(IDataServiceConfiguration config)
{
config.SetEntitySetAccessRule("Customers", EntitySetRights.AllRead);
config.SetServiceOperationAccessRule("CustomersInCity", ServiceOperationRights.All);
}
[WebGet]
public IQueryable<MyDataSource.Customers> CustomersInCity(string city)
{
return from c in this.CurrentDataSource.Customers
where c.City == city
select c;
}
}
How can I get CustomersInCity() to show up in my client-side class defintions?

When you see your Odata in browser, you will see link ...
e.g. http://localhost:1234/odataService.svc
just write your method name after the link
for your method it will be something like this...
http://localhost:1234/odataService.svc/CustomersInCity?city="London"

Related

Audit accesses to a JPA entity

I have a JPA entity, with its attibutes and several NamedQueries.
I'm trying to log some information "any time the entity is used for something", i.e.:
any time any of its NamedQueries is invoked
any time the entity is used in a Query q = em.createQuery("SELECT....FROM thisEntity a, otherEntity b WHERE.....");
any time any of its attributes is accessed
The information i want to log must include the invoker class name and invoker method, among other.
I guess this must be achieved through interceptors, but i'm not sure for example if interceptors allow me to intercept the accesses to the class throw its NamedQueries.
You could achieve that using callback methods like #PrePersist, #PostPersist, #PostLoad, #PreUpdate, #PostUpdate, #PreRemove, #PostRemove inside the entity classes.
For example
public class EntityA {
...
#PrePersist
public void beforePersist(){
//Log information
}
}
Additionally you could use that callback methods in listener classes.
public class EntityListenerA{
#PrePersist
public void beforePersist(EntityA ob) {
//Log information
}
}
#EntityListeners(EntityListenerA.class)
public class EntityA {
...
}
In your case I supose you must use the callback #PostLoad depending on the query.
Hope this help

Web Api 2 Inheritance No route providing a controller name was found to match request URI

Basically I cannot get my Web Api 2 application to work.
First of all here are my requirements.
In my application I am creating a dozen of controllers ( ProductController, ItemController, SalesController...etc). There are 2 actions which are absolutely common in all my controllers:
FetchData, PostData
(Each controller then may implement a number of other methods which are sepcific to its business domain )
Instead of repeating these actions in every controllers like:
public class ProductController:ApiController{
[HttpPost]
public MyReturnJson FetchData( MyJsonInput Input){
....
return myJsonResult;
}
}
public class SalesController:ApiController{
[HttpPost]
public MyReturnJson FetchData( MyJsonInput Input){
....
return myJsonResult;
}
}
I decided to create a base controller MyBaseController:
public class MyBaseController : ApiController{
[HttpPost]
public MyReturnJson FetchData( MyJsonInput Input){
....
return myJsonResult;
}
}
with the 2 methods so every other controller would inherit them (It saves me from repeating them in every controller). The common base class has been defined and implemented in a separate assembly which is then referenced in my web project.
Then in my javascript client (using breeze) I call a specific controller like
breeze.EntityQuery.from('FetchData')
where my serviceName is 'my_api/product/'
(in the WebApiConfig, the routing table has been defined like:
config.Routes.MapHttpRoute(
name: "my_api",
routeTemplate: "my_api/{controller}/{action}"
);
But when the javascript code is executed I get the error message:
No route providing a controller name was found to match request URI
http://localhost:xxxxx/my_api/product/FetchData
If I don't use a common base class but instead repeat this method (FetchData) in every class (basically ProductController inherits directly from ApiController and not from MyBaseController) every thing works fine and my method is hit. I thing there is a problem with the inheritance scheme. Maybe there is something I don't get (first time using Web Api 2) or some constraints (routing, configuration...) I do not respect. Right now I am stuck and I would appreciate any suggestion which might point me to the right direction. Is inheritance allowed in Web Api 2?
I am not sure why your code is not working. But in the next link (http://www.asp.net/web-api/overview/releases/whats-new-in-aspnet-web-api-22#ARI) you can see an example of inheritance using attribute routing.
This is the code example:
public class BaseController : ApiController
{
[Route("{id:int}")]
public string Get(int id)
{
return "Success:" + id;
}
}
[RoutePrefix("api/values")]
public class ValuesController : BaseController
{
}
config.MapHttpAttributeRoutes(new CustomDirectRouteProvider());
public class CustomDirectRouteProvider : DefaultDirectRouteProvider
{
protected override IReadOnlyList<IDirectRouteFactory>
GetActionRouteFactories(HttpActionDescriptor actionDescriptor)
{
return actionDescriptor.GetCustomAttributes<IDirectRouteFactory>
(inherit: true);
}
}
I hope that it helps.

#Category in AutoBean

Am totally lost trying to understand the #Category annotation of AutoBean. Can somebody please tell me how exactly it can be used?
I went through the example in wiki as well. My doubt is like this.
Say I am having a proxy interface in the client side which extends entity proxy, and I want to insert a non setter/getter method in that interface, how can I do that?
#ProxyFor( value = CacheStrategy.class )
public interface CacheStrategyProxy extends EntityProxy
{
// setters and getters
CacheStrategyProxy fetchObject(int id);
}
#Category(CacheStrategyProxyCategory.class)
interface MyFactory extends AutoBeanFactory {
AutoBean<CacheStrategyProxy> fetchObject();
}
class CacheStrategyProxyCategory {
public static CacheStrategyProxy fetchObject (AutoBean<CacheStrategyProxy> instance, int id) {
// return data
}
}
Am writing all this in my CacheStrategyProxy file. But I still get the error "Only setters and getters allowed". Pardon me if I have done something silly here. I am totally new to this world.
#Category cannot be used with Request Factory (at least not currently).
Request Factory makes use of AutoBeans (and your proxies will be AutoBean instances) but the AutoBeanFactory (factories actually) is/are internal to the RequestFactory, and you cannot tweak them.

Decouple EF queries from BL - Extension Methods VS Class-Per-Query

I have read dozens of posts about PROs and CONs of trying to mock \ fake EF in the business logic.
I have not yet decided what to do - but one thing I know is - I have to separate the queries from the business logic.
In this post I saw that Ladislav has answered that there are 2 good ways:
Let them be where they are and use custom extension methods, query views, mapped database views or custom defining queries to define reusable parts.
Expose every single query as method on some separate class. The method
mustn't expose IQueryable and mustn't accept Expression as parameter =
whole query logic must be wrapped in the method. But this will make
your class covering related methods much like repository (the only one
which can be mocked or faked). This implementation is close to
implementation used with stored procedures.
Which method do you think is better any why ?
Are there ANY downsides to put the queries in their own place ? (maybe losing some functionality from EF or something like that)
Do I have to encapsulate even the simplest queries like:
using (MyDbContext entities = new MyDbContext)
{
User user = entities.Users.Find(userId); // ENCAPSULATE THIS ?
// Some BL Code here
}
So I guess your main point is testability of your code, isn't it? In such case you should start by counting responsibilities of the method you want to test and than refactor your code using single responsibility pattern.
Your example code has at least three responsibilities:
Creating an object is a responsibility - context is an object. Moreover it is and object you don't want to use in your unit test so you must move its creation elsewhere.
Executing query is a responsibility. Moreover it is a responsibility you would like to avoid in your unit test.
Doing some business logic is a responsibility
To simplify testing you should refactor your code and divide those responsibilities to separate methods.
public class MyBLClass()
{
public void MyBLMethod(int userId)
{
using (IMyContext entities = GetContext())
{
User user = GetUserFromDb(entities, userId);
// Some BL Code here
}
}
protected virtual IMyContext GetContext()
{
return new MyDbContext();
}
protected virtual User GetUserFromDb(IMyDbContext entities, int userId)
{
return entities.Users.Find(userId);
}
}
Now unit testing business logic should be piece of cake because your unit test can inherit your class and fake context factory method and query execution method and become fully independent on EF.
// NUnit unit test
[TestFixture]
public class MyBLClassTest : MyBLClass
{
private class FakeContext : IMyContext
{
// Create just empty implementation of context interface
}
private User _testUser;
[Test]
public void MyBLMethod_DoSomething()
{
// Test setup
int id = 10;
_testUser = new User
{
Id = id,
// rest is your expected test data - that is what faking is about
// faked method returns simply data your test method expects
};
// Execution of method under test
MyBLMethod(id);
// Test validation
// Assert something you expect to happen on _testUser instance
// inside MyBLMethod
}
protected override IMyContext GetContext()
{
return new FakeContext();
}
protected override User GetUserFromDb(IMyContext context, int userId)
{
return _testUser.Id == userId ? _testUser : null;
}
}
As you add more methods and your application grows you will refactor those query execution methods and context factory method to separate classes to follow single responsibility on classes as well - you will get context factory and either some query provider or in some cases repository (but that repository will never return IQueryable or get Expression as parameter in any of its methods). This will also allow you following DRY principle where your context creation and most commonly used queries will be defined only once on one central place.
So at the end you can have something like this:
public class MyBLClass()
{
private IContextFactory _contextFactory;
private IUserQueryProvider _userProvider;
public MyBLClass(IContextFactory contextFactory, IUserQueryProvider userProvider)
{
_contextFactory = contextFactory;
_userProvider = userProvider;
}
public void MyBLMethod(int userId)
{
using (IMyContext entities = _contextFactory.GetContext())
{
User user = _userProvider.GetSingle(entities, userId);
// Some BL Code here
}
}
}
Where those interfaces will look like:
public interface IContextFactory
{
IMyContext GetContext();
}
public class MyContextFactory : IContextFactory
{
public IMyContext GetContext()
{
// Here belongs any logic necessary to create context
// If you for example want to cache context per HTTP request
// you can implement logic here.
return new MyDbContext();
}
}
and
public interface IUserQueryProvider
{
User GetUser(int userId);
// Any other reusable queries for user entities
// Non of queries returns IQueryable or accepts Expression as parameter
// For example: IEnumerable<User> GetActiveUsers();
}
public class MyUserQueryProvider : IUserQueryProvider
{
public User GetUser(IMyContext context, int userId)
{
return context.Users.Find(userId);
}
// Implementation of other queries
// Only inside query implementations you can use extension methods on IQueryable
}
Your test will now only use fakes for context factory and query provider.
// NUnit + Moq unit test
[TestFixture]
public class MyBLClassTest
{
private class FakeContext : IMyContext
{
// Create just empty implementation of context interface
}
[Test]
public void MyBLMethod_DoSomething()
{
// Test setup
int id = 10;
var user = new User
{
Id = id,
// rest is your expected test data - that is what faking is about
// faked method returns simply data your test method expects
};
var contextFactory = new Mock<IContextFactory>();
contextFactory.Setup(f => f.GetContext()).Returns(new FakeContext());
var queryProvider = new Mock<IUserQueryProvider>();
queryProvider.Setup(f => f.GetUser(It.IsAny<IContextFactory>(), id)).Returns(user);
// Execution of method under test
var myBLClass = new MyBLClass(contextFactory.Object, queryProvider.Object);
myBLClass.MyBLMethod(id);
// Test validation
// Assert something you expect to happen on user instance
// inside MyBLMethod
}
}
It would be little bit different in case of repository which should have reference to context passed to its constructor prior to injecting it to your business class.
Your business class can still define some queries which are never use in any other classes - those queries are most probably part of its logic. You can also use extension methods to define some reusable part of queries but you must always use those extension methods outside of your core business logic which you want to unit test (either in query execution methods or in query provider / repository). That will allow you easy faking query provider or query execution methods.
I saw your previous question and thought about writing a blog post about that topic but the core of my opinion about testing with EF is in this answer.
Edit:
Repository is different topic which doesn't relate to your original question. Specific repository is still valid pattern. We are not against repositories, we are against generic repositories because they don't provide any additional features and don't solve any problem.
The problem is that repository alone doesn't solve anything. There are three patterns which have to be used together to form proper abstraction: Repository, Unit of Work and Specifications. All three are already available in EF: DbSet / ObjectSet as repositories, DbContext / ObjectContext as Unit of works and Linq to Entities as specifications. The main problem with custom implementation of generic repositories mentioned everywhere is that they replace only repository and unit of work with custom implementation but still depend on original specifications => abstraction is incomplete and it is leaking in tests where faked repository behaves in the same way as faked set / context.
The main disadvantage of my query provider is explicit method for any query you will need to execute. In case of repository you will not have such methods you will have just few methods accepting specification (but again those specifications should be defined in DRY principle) which will build query filtering conditions, ordering etc.
public interface IUserRepository
{
User Find(int userId);
IEnumerable<User> FindAll(ISpecification spec);
}
The discussion of this topic is far beyond the scope of this question and it requires you to do some self study.
Btw. mocking and faking has different purpose - you fake a call if you need to get testing data from method in the dependency and you mock the call if you need to assert that method on dependency was called with expected arguments.

Dependency Injection & Model Binding (ASP MVC, Autofac), When to use what?

This is more like a conceptual question. When to use Model Binding (in ASP.NET MVC Framework) and when to inject objects using IoC (lets say Autofac here) ?
One specific scenario is like lets say, I have the following action method
public ActionResult EditProfile(string UserId)
{
// get user object from repository using the the UserId
// edit profile
// save changes
// return feedback
}
In the above scenario, is it possible to inject a user object to action method such that it automatically gets the user object using the UserId ? The resulting signature being:
public ActionResult EditProfile(UserProfile userObj) //userObj injected *somehow* to automatically retreive the object from repo using UserId ?
Sorry if it all doesn't makes sense. It`s my first time using IoC.
EDIT:
This is the way to do it > http://buildstarted.com/2010/09/12/custom-model-binders-in-mvc-3-with-imodelbinder/
You can do what you need using a custom action filter. By overriding OnActionExecuting, we have access to the route data, and the action parameters of the action that will be executed. Given:
public class BindUserProfileAttribute : ActionFilterAttribute
{
public override OnActionExecuting(FilterContext filterContext)
{
string id = (string)filterContext.RouteData.Values["UserId"];
var model = new UserProfile { Id = id };
filtextContext.ActionParameters["userObj"] = model;
}
}
This attribute allows us to create the parameters that will be passed into the action, so we can load the user object at this point.
[BindUserProfile]
public ActionResult EditProfile(UserProfile userObj)
{
}
You'll probably need to get specific with your routes:
routes.MapRoute(
"EditProfile",
"Account/EditProfile/{UserId}",
new { controller = "Account", action = "EditProfile" });
In MVC3 we get access to the new IDepedencyResolver interface, which allows us to perform IoC/SL using whatever IoC container or service locator we want, so we can push a service like a IUserProfileFactory into your filter, to then be able to create your UserProfile instance.
Hope that helps?
Model binding is used for your data. Dependency injection is used for your business logic.