Entity Framework with Poco and navigation properties - entity-framework-4

I am using Poco Generator with entity framework,
And Poco Proxy class have been generated successfully,
For a single table all the things goes fine,
herein I've listed the main part of my classes and explain relations between tables.
There are 3 table that they have many-to-many relation as follows:
1- Authority 2- Ability 3- AuthorityAbilityMap
Each Authority can have many Ability and vice verse.
The main problem is that Navigation property in Authority Class doesn't work.
The Authority class is (just a part of class listed):
public partial class Authority
{
.
.
.
public virtual ICollection<AuthorityAbilityMap> AuthorityAbilityMaps
{
//Poco implementation
}
private ICollection<AuthorityAbilityMap> _authorityAbilityMaps;
.
.
.
}
And Ability class:
public partial class Ability : IAuditable
{
.
.
.
public virtual ICollection<AuthorityAbilityMap> AuthorityAbilityMaps
{
//Poco implementation contains get and set.
}
private ICollection<AuthorityAbilityMap> _authorityAbilityMaps;
}
And AuthorityAbilityMaps navigation properties:
public virtual Ability Ability
{
get { return _ability; }
set
{
if (!ReferenceEquals(_ability, value))
{
var previousValue = _ability;
_ability = value;
FixupAbility(previousValue);
}
}
}
private Ability _ability;
public virtual Authority Authority
{
get { return _authority; }
set
{
if (!ReferenceEquals(_authority, value))
{
var previousValue = _authority;
_authority = value;
FixupAuthority(previousValue);
}
}
}
The source code tested against above classes is as following :
AuthorityEntities authorityContext = new AuthorityEntities();
Authority authority = authorityContext.Authorities.Where(x => x.AID == 85).FirstOrDefault();
ICollection<AuthorityAbilityMap> allMaped = authority.AuthorityAbilityMaps;
allMaped contains 0 member.
As you know the navigation properties will created by Poco Generator,
In fact I want to use these Navigation properties to load all relation-ed records and
supply multiple Ability in bulk for a specific Authority.
Thanks in advance.

I defined Authority's primary key and Ability's primary key as primary keys
for AuthorityAbilityMap and it works well,
they have been used as foreign keys in AuthorityAbilityMap.

Related

Resolve Service Implementation from Autofac based on Runtime Session Value

Need some help trying to solve a problem resolving an implementation of a service at runtime based on a parameter. In other words use a factory pattern with DI.
We have Autofac wired in to our MVC application. I am trying to figure out how we can use a user session variable (Call it Ordering Type) to be used for the Dependency Resolver to resolve the correct implementation of a service.
An example of what we are trying to do.
The application has two "types" of ordering - real eCommerce type of ordering (add stuff to a shopping cart, checkout etc).
The other is called Forecast ordering. Users create orders - but they do not get fulfilled right away. They go through an approval process and then fulfilled.
The bottom line is the data schema and back end systems the application talks to changes based on the order type.
What I want to do is:
I have IOrderManagerService
public interface IOrderManagerService
{
Order GetOrder(int orderNumber);
int CreateOrder(Order order);
}
Because we have two ordering "types" - I have two implementations of the the IOrderManagerService:
public class ShelfOrderManager : IOrderManagerService
{
public Order GetOrder(int orderMumber)
{
...code
}
public int CreateOrder(Order order)
{
...code
}
}
and
public class ForecastOrderManager: IOrderManagerService
{
public Order GetOrder(int orderMumber)
{
...code
}
public int CreateOrder(Order order)
{
...code
}
}
My First question is - in my MVC application - do I register these implementations as?
builder.RegisterType<ShelfOrderManager>().As<IOrderManagerService>();
builder.RegisterType<ForecastOrderManager>().As<IOrderManagerService>();
What we are planning on doing is sticking the user selected ordering type in a users session. When a user wants to view order status - depending on their selected ordering "type" - I need the resolver to give the controller the correct implementation.
public class OrderStatusController : Controller
{
private readonly IOrderManagerService _orderManagerService;
public OrderStatusController(IOrderManagerService orderManagerService)
{
//This needs to be the correct implementation based on the users "type".
_orderManagerService = orderManagerService;
}
public ActionResult GetOrder(int orderNumber)
{
var model = _orderManagerService.GetOrder(orderNumber);
return View(model);
}
}
I've ready about the the delegate factory and this answer explains the concept well.
The problem is the runtime parameters are being used to construct the service and resolve at runtime. i.e.
var service = resolvedServiceClass.Factory("runtime parameter")
All this would do is give me "service" that used the "runtime parameter" in the constructor.
I've looked at Keyed or Named resolution too.
At first I thought I could combine these two techniques - but the controller has the dependency on the interface - not the concrete implementation. (as it should)
Any ideas on how to get around this would be MUCH appreciated.
As it would turn out we were close. #Andrei is on target with what we did. I'll explain the answer below for the next person that comes across this issue.
To recap the problem - I needed to resolve a specific concrete implementation of an interface using Autofac at run time. This is commonly solved by the Factory Pattern - but we already had DI implemented.
The solution was using both. Using the delegate factory Autofac supports, I created a simple factory class.
I elected to resolve the component context privately
DependencyResolver.Current.GetService<IComponentContext>();
versus having Autofac resolve it predominately so I did not have to include IComponentContext in all of my constructors that that will be using the factory.
The factory will be used to resolve the services that are dependent on run time parameters - which means wherever a
ISomeServiceThatHasMultipleImplementations
is used in a constructor - I am going to replace it with ServiceFactory.Factory factory. I did not want to ALSO include IComponentContext wherever I needed the factory.
enum OrderType
{
Shelf,
Forecast
}
public class ServiceFactory : IServiceFactory
{
private readonly IComponentContext _componentContext;
private readonly OrderType _orderType;
public ServiceFactory(OrderType orderingType)
{
_componentContext = DependencyResolver.Current.GetService<IComponentContext>();
_orderType = orderingType;
}
public delegate ServiceFactory Factory(OrderType orderingType);
public T Resolve<T>()
{
if(!_componentContext.IsRegistered<T>())
return _componentContext.ResolveNamed<T>(_orderType.ToString());
return _componentContext.Resolve<T>();
}
}
With the factory written, we also used the Keyed services.
Using my order context -
public interface IOrderManagerService
{
Order GetOrder(int orderNumber);
int CreateOrder(Order order);
}
public class ShelfOrderManager : IOrderManagerService
{
public Order GetOrder(int orderNumber)
{
...
}
public int CreateOrder(Order order)
{
...
}
}
public class ForecastOrderManager : IOrderManagerService
{
public Order GetOrder(int orderNumber)
{
...
}
public int CreateOrder(Order order)
{
...
}
}
The registration of Keyed services:
//register the shelf implementation
builder.RegisterType<ShelfOrderManager>()
.Keyed(OrderType.Shelf)
.As<IOrderManager>();
//register the forecast implementation
builder.RegisterType<ForecastOrderManager>()
.Keyed(OrderType.Shelf)
.As<IOrderManager>();
Register the factory:
builder.RegisterType<IMS.POS.Services.Factory.ServiceFactory>()
.AsSelf()
.SingleInstance();
Finally using it in the controllers (or any other class for that matter):
public class HomeController : BaseController
{
private readonly IContentManagerService _contentManagerService;
private readonly IViewModelService _viewModelService;
private readonly IApplicationSettingService _applicationSettingService;
private readonly IOrderManagerService _orderManagerService;
private readonly IServiceFactory _factory;
public HomeController(ServiceFactory.Factory factory,
IViewModelService viewModelService,
IContentManagerService contentManagerService,
IApplicationSettingService applicationSettingService)
{
//first assign the factory
//We keep the users Ordering Type in session - if the value is not set - default to Shelf ordering
_factory = factory(UIUserSession?.OrderingMode ?? OrderType.Shelf);
//now that I have a factory to get the implementation I need
_orderManagerService = _factory.Resolve<IOrderManagerService>();
//The rest of these are resolved by Autofac
_contentManagerService = contentManagerService;
_viewModelService = viewModelService;
_applicationSettingService = applicationSettingService;
}
}
I want to work out a bit more handling of the Resolve method - but for the first pass this works. A little bit Factory Pattern (where we need it) but still using Autofac to do most of the work.
I would not rely on Autofac for this. IOC is used to resolve a dependency and provide an implementation for it, what you need is to call a different implementation of the same interface based on a decision flag.
I would use a simple factory basically, like a class with 2 static methods and call whichever implementation you need need to when you know what the decision is. This gives you the run-time resolver you are after. Keep it simple I'd say.
This being said it seems there is another option. Have a look at the "select by context" option, maybe you can redesign your classes to take advantage of this: http://docs.autofac.org/en/latest/faq/select-by-context.html

How do you add a runtime string parameter into a dependency resolution chain?

How could I setup my chosen DI for this kind of setup:
public abstract class BaseRepo
{
public BaseRepo(string token)
{
}
}
public RepoA : BaseRepo, IRepoA
{
// implementation of interface here
}
public ViewModelA
{
IRepoA _repo;
public ViewModelA(IRepoA repo)
{
this._repo = repo;
}
public DoMethod()
{
this._repo.DoSomeStuff();
}
}
In real scenario, the token parameter on the base class is resolved after the user has been logged in. I was thinking of just configuring the interfaces for DI after the login but I'm not sure if that a right thing do.
I looked at some Factories but I can't make it to work.
My choice of DI probably goes to AutoFac/Ninject and the project is Xamarin mobile app
In real scenario, the token parameter on the base class is resolved
after the user has been logged in.
This means that the token parameter is runtime data. Prevent injecting runtime data into your components. Your components should be stateless. Instead, runtime data should be passed on through method calls through the previously constructed object graph of components. Failing to do so, will make it much more complicated to configure and verify your object graphs.
There are typically to ways of passing runtime data. Either you pass it on through method calls from method to method through the object graph, or your components call a method that returns that correct value. This token seems like it is contextual information and that would typically mean you choose the latter option:
public interface ITokenProvider {
string GetCurrentToken();
}
// Don't use base classes: base classes are a design smell!
public RepoA : IRepoA
{
private readonly ITokenProvider tokenProvider;
public RepoA(ITokenProvider tokenProvider) {
this.tokenProvider = tokenProvider;
}
// IRepoA methods
public A GetById(Guid id) {
// Get token at runtime
string token = this.tokenProvider.GetCurrentToken();
// Use token here.
}
}
In your Composition Root, you will have to create an implementation for this ITokenProvider. How this implementation looks is highly dependent on how you wish to store this token, but here's a possible implementation:
public sealed class AspNetSessionTokenProvider : ITokenProvider {
public string GetCurrentToken() {
return (string)HttpContext.Current.Session["token"];
}
}

Grails many to many using a third 'join' class

I read that a m:m relationship often means there is a third class that isn't yet required. So I have m:m on User and Project, and I created a third domain class, ProjectMembership
The three domains are as follows (minimized for illustration purposes):
User
class User {
String name
static hasMany = [projectMemberships : ProjectMembership]
}
Project Membership
class ProjectMembership {
static constraints = {
}
static belongsTo = [user:User, project:Project]
}
Project:
class Project {
String name
static hasMany = [projectMemberships : ProjectMembership]
static constraints = {
}
}
If I have the ID of the user, how can I get a list of Project objects that they are assigned to?
There are a handful of ways - here are a couple:
def user = User.get(userId)
ProjectMembership.findAllByUser(user).collect { it.project }
or to avoid the query for the User:
ProjectMembership.withCriteria {
user {
eq('id', userId)
}
}.collect { it.project }
Be wary of queries that'll return large result sets - you'll end up with a huge in-memory list of project objects.

Set Inner Dependency by Type using Structuremap

I have a structuremap configuration that has me scratching my head. I have a concrete class that requires a interfaced ui element which requires an interfaced validation class. I want the outer concrete class to get the default ui element, but get a concrete-class-specific validation object. Something like this:
class MyView
{
IPrompt prompt
}
class GenericPrompt : IPrompt
{
IValidator validator
}
class MyValidator : IValidator
{
bool Validate() {}
}
How can I configure structuremap with the Registry DSL to only use MyValidator when creating dependencies for MyView. (And assumedly using BobsValidator when creating dependencies for BobsView)
Are you getting MyView (and BobsView) from the container? Can we assume that they will all take an instance of IPrompt?
One approach would be to register all of your validators with a name that matches the names of your view. You could implement your own type scanner that just removes the Validator suffix:
public class ValidatorScanner : ITypeScanner
{
public void Process(Type type, PluginGraph graph)
{
if (!typeof (IValidator).IsAssignableFrom(type)) return;
var validatorName = type.Name.Replace("Validator", "");
graph.AddType(typeof(IValidator), type, validatorName);
}
}
Now, if you assume an IPrompt will always be requested by a View that follows that naming convention, your registry could look like:
public class ValidatorRegistry : Registry
{
public ValidatorRegistry()
{
Scan(scan =>
{
scan.TheCallingAssembly();
scan.With<ValidatorScanner>();
});
ForRequestedType<IPrompt>().TheDefault.Is.ConstructedBy(ctx =>
{
var viewName = ctx.Root.RequestedType.Name.Replace("View", "");
ctx.RegisterDefault(typeof(IValidator), ctx.GetInstance<IValidator>(viewName));
return ctx.GetInstance<GenericPrompt>();
});
}
}
To retrieve your view with the appropriate validator, you would have to request the concrete type:
var view = container.GetInstance<MyView>();
Note that this will only work if you are retrieving your view with a direct call to the container (service location), since it depends on the "Root.RequestedType". Depending on how you plan to get your views, you might be able to walk up the BuildStack looking for a View (instead of assuming it is always Root).

How to Filter Model with Interface in View

in my view
Inherits="System.Web.Mvc.ViewUSerControl<Model.Person>"
How can I use an interface to restrict what the view is capable of accessing from the model? is this safe?
Let Person class has several properties and you want only Name property be accessible from a view. Declare interface like this and use it:
public interface RestrictedPerson
{
string Name
{
get;
set;
}
}
public partial class Person: RestrictedPerson
{
}
in a view's Page directive set
Inherits="System.Web.Mvc.ViewPage<Model.RestrictedPerson>
and pass to view Person object as usual.

Resources