Unity 3, generic type not resolving, type does not have an accessible constructor - unity-container

I have the following registration. The goal is that when IDbSet needs to be injected it will be extracted out of the requests IDataContext.
container.RegisterType<IDbSet<AuditRound>>(new InjectionFactory(c => c.Resolve<IDataContext>().AuditRounds));
var thisReturnsTrue = container.Registrations.Any(e => e.RegisteredType == typeof(IDbSet<AuditRound>));
var fails = container.Resolve<IDbSet<AuditRound>>();
it fails with the message that The type DbSet`1 does not have an accessible constructor. It seems like it's trying to use the convention ISomeClass resolves to SomeClass, in this case IDbSet to DbSet. I do see a registration for IDbSet in the registrations and it seems to be taking precedence. Any help is appreciated. Thanks.

My issue turned out to be that the convention registration "RegisterTypes" was registering IDbSet to DbSet. This registration was taking precedence over my own other registration. I tried changing the order but that did not help. I had to exclude DbSet from my registration routine. Exclusions are a parameter on container.RegisterTypes.

Related

Mocking a signed in Identity User

I am using Moq and xUnit to create unit tests. However, because of the way my action methods are set up, I'm having a hard time doing so. In my controller, I use
var user = await userManager.FindByNameAsync(User.Identity.Name);
to get the the signed in user information. I used this approach to avoid the number of parameters Is there a way to mock this in a unit test, or should the controller be set up differently?
The AppUser class extends IdentityUser for specific properties that are used within the controller.
For mocking above you can do something like following,
Mock<UserManager<User>> userManagerMock = new Mock<UserManager<User>>();
userManagerMock
.Setup(m => m.FindByNameAsync(It.IsAny<string>()))
.Returns(Task.FromResult(It.IsAny<User>()));
Please note I haven't compiled this code, but you should be able to get the idea.

What is the proper way to inject (via constructor) different types that implement that same interface?

For example, let's say I have an interface 'IFeed' and two concrete types ('Feed1' and 'Feed2') that implement this interface. Now let's say I have a 'FeedManager' type that takes multiple parameters that will get resolved dynamically, two of which are of type 'IFeed' and I'd like both concrete type to be injected via constructor injection, not via manual resolve (I only use resolve once at the composition root). I have a feeling that I should be using a factory but I wanted to see what the proper way of doing this might be. Many thanks in advance.
If you want ALL implementations of IFeed, you can use array syntax in your constructor and then nothing special is needed at type registration time.
container.RegisterType<IFeedManager, FeedManager>();
container.RegisterType<IFeed, FeedA>("FeedA"); // The name doesn't matter
container.RegisterType<IFeed, FeedB>("FeedB"); // The name doesn't matter
Then the manager constructor...
public FeedManager(IFeed[] feeds) {...}
or if you want to add a little flare for calling the constructor directly...
public FeedManager(params IFeed[] feeds) {...}
Assuming you want to determine the actual concrete instances at runtime, you need to use named type registrations and then tell unity which one you want. So, use a factory method to construct the types required and pass those in as parameter overrides. Unity will use the overrides and resolve any remaining dependencies.
// register the types using named registrations
container.RegisterType<IFeedManager,FeedManager>()
container.RegisterType<IFeed, Feed1>("Feed1")
container.RegisterType<IFeed, Feed2>("Feed2")
Assuming your feed manager has the following named constructor parameters
class FeedManager : IFeedManager
{
public FeedManager (IFeed Feed1, IFeed Feed2, string someOtherDependency)
{
}
}
and create your feed manager:
static IFeedManager CreateFeedManager()
{
ParameterOverride feed1 = new ParameterOverride("Feed1"
,_container.Resolve<IFeed>("feed1"));
ParameterOverride feed2 = new DependencyOverride("Feed2"
,_container.Resolve<IFeed>("feed2"));
IFeedManager = _container.Resolve<IFeedManager>(feed1,feed2)
return IFeedManager;
}
Obviously this is overly simplified, but you you insert your own logic to determine which instance is to be resolved and then injected for each of the IFeed instances required by the FeedManager.
With Unity you would do this like so:
container.RegisterType<IFeed, Feed1>("Feed1");
container.RegisterType<IFeed, Feed2>("Feed2");
container.RegisterType<FeedManager>(new InjectionConstructor(new ResolvedParameter<IFeed>("Feed1"),
new ResolvedParameter<IFeed>("Feed2")));
This has now configured Unity so that when it needs to resolve a FeedManager, it will resolve Feed1 for the first parameter and Feed2 for the second parameter.

forward request to controller action

i'd like to forward a request to a controller to some specific action without redirecting to another url.
so, for example, the following url:
/home/peter
should internally become
/home/people/peter
i know i could catch the action name ('peter') in the 'init' function, then do a Controller::redirect, but i'd like to stay on the same url, just have the request internally forwarded to the 'people' action.
2 things to note:
'peter' is a dynamic string, so i can't just hardcode a route for this
any other action of the controller shall still work, so only a couple of strings should get forwared (eg. 'peter', 'ann' get forwarded to the 'people' action, whereas 'otherAction' is still callable)
i already found the 'handleAction' and 'handleRequest' methods in the Controller class, but just can't imagine how make use of them for my task.
SilverStripe version: 3.0.3
I suggest the use of static $url_handlers described here, that allows you to define specific routes to actions. Your use case could be achieved by using a catch-all url-handler.
But therefore we have to pay attention to the order of each route. The catch-all route has to be defined at the end. All other actions need a seperate url handler before:
public static $url_handlers = array(
'otherAction' => 'otherAction',
// ...
'people/$Name' => 'people',
'$Name' => 'people' // catch-all
);
This should fit to your explanation. The last route catches all dynamic routes which weren't handled before.
But as Ingo mentioned, both routes would deliver the same content and that could be bad for SEO. You could target the second route people/$Name to a different action which does a 301 redirect to the url with $Name only. I would recommend this if you already have public content and you want to replace the existing URLs with the short version.
I hope this solves your problem (temporarily).
First of all, I assume you have good reasons for making duplicate URLs (bad for SEO) :)
I've tried around a bit with Director::direct(), which would be the cleanest, but didn't get anywhere. Director::test() resets most request state, so doesn't qualify either.
Calling handleRequest() or handleAction() on a new controller instance is tricky, because the Director has built up a lot of state by that time already (for example pushed to the controller stack).
So, unfortunately the SilverStripe routing isn't that flexible, anything you do will go deep into system internals, and potentially break with the next release.

How do I call a method from a Domain Service class

Once again I am in need of some assistance with regard to calling a Domain Service class method from silverlight.
This ties in somewhat to my question of yesterday which was solved. Thanks again!
For those who are interested, my question of yesterday can be found here:
Using ASP.net membership to get aspnet_Users in silverlight
Now onto my current question.
I have the following method in Domain Service Class called MembershipData
[RequiresRole("Managers")]
public void DeleteUser(MembershipServiceUser user)
{
Membership.DeleteUser(user.UserName);
}
This code is from kylemc's tutorial
Now how do I call this method from within Silverlight?
I understand from yesterday's question that
public IEnumerable<MembershipServiceUser> GetAllUsers()
needs to be called by defining the query, then running the query and then calling OnGetAllUsersLoaded when the the results return.
What I am unsure of is, Do you need to call the method in this way because of its return type?
Obviously public void DeleteUser(MembershipServiceUser user) has no return type so cannot be called in this way.
It does not seem to be possible to do:
MembershipDataContext context = new MembershipDataContext();
MembershipServiceUser user = new MembershipServiceUser();
user.UserName = "bob";
context.DeleteUser(user);
But then how do I use the DeleteUser method?
Any assistance is greatly appreciated.
Kind regards,
Neill
Update
Thanks for the info HiTech. I still have one issue I need to solve. Perhaps I am still not doing something correctly.
I am now creating a new instance of MembershipServiceUser, lets call it msu.
Then assigning msu.UserName and msu.Email the user details, and after that calling
context.MembershipServiceUsers.Remove(msu)
where context is my MembershipData domain service context, and I have checked that
context MembershipServiceUsers results
does have my user info. I then however get the following error
"The specified entity is not contained in this EntitySet."
I am positive the data in msu is correct, so any ideas as to why I am getting this error?
Many thanks
Update 2
Am I on the right track with something like the following...
MembershipServiceUser usr = (from a in context.MembershipServiceUsers
where a.UserName == "bob"
select a).First();
context.MembershipServiceUsers.Remove(usr);
context.SubmitChanges(DeleteUser_completed, null);
Or is this way off? because in my callback DeleteUser_completed(SubmitOperation so)
so.HasError = true
while so's ChangeSet -> RemovedEntities = 1, but so's EntitiesInError's result is "enumeration yielded no results"
Once again thanks for helping steer me in the right direction.
RIA services works by creating a change set (literally a set of changes) and sending just those changes to the server. The methods to do CRUD are more like Entity Framework, not direct method calls.
On the client side you will call the Remove method on the domain context's User collection.
On the receiving side it goes through all the changes and says:
Q. "Is this an object deletion?"
A. Yes...
Q. "What object type is it?"
A. MembershipServiceUser
Q. "Do we have a method called Delete that takes a MembershipServiceUser parameter?"
A. Yes...
It then calls that method with the object from the changeset...

Asp.net MVC RouteBase and IoC

I am creating a custom route by subclassing RouteBase. I have a dependency in there that I'd like to wire up with IoC. The method GetRouteData just takes HttpContext, but I want to add in my unit of work as well....somehow.
I am using StructureMap, but info on how you would do this with any IoC framework would be helpful.
Well, here is our solution. Many little details may be omitted but overall idea is here. This answer may be a kind of offtop to original question but it describes the general solution to the problem.
I'll try to explain the part that is responsible for plain custom HTML-pages that are created by users at runtime and therefore can't have their own Controller/Action. So the routes should be either somehow built at runtime or be "catch-all" with custom IRouteConstraint.
First of all, lets state some facts and requirements.
We have some data and some metadata about our pages stored in DB;
We don't want to generate a (hypothetically) whole million of routes for all of existing pages beforehand (i.e. on Application startup) because something can change during application and we don't want to tackle with pushing the changes to global RouteCollection;
So we do it this way:
1. PageController
Yes, special controller that is responsible for all our content pages. And there is the only action that is Display(int id) (actually we have a special ViewModel as param but I used an int id for simplicity.
The page with all its data is resolved by ID inside that Display() method. The method itself returns either ViewResult (strongly typed after PageViewModel) or NotFoundResult in case when page is not found.
2. Custom IRouteConstraint
We have to somewhere define if the URL user actually requested refers to one of our custom pages. For this we have a special IsPageConstraint that implements IRouteConstraint interface. In the Match() method of our constraint we just call our PageRepository to check whether there is a page that match our requested URL. We have our PageRepository injected by StructureMap. If we find the page then we add that "id" parameter (with the value) to the RouteData dictionary and it is automatically bound to PageController.Display(int id) by DefaultModelBinder.
But we need a RouteData parameter to check. Where we get that? Here comes...
3. Route mapping with "catch-all" parameter
Important note: this route is defined in the very end of route mappings list because it is very general, not specific. We check all our explicitly defined routes first and then check for a Page (that is easily changeable if needed).
We simply map our route like this:
routes.MapRoute("ContentPages",
"{*pagePath}",
new { controller = "Page", action = "Display" }
new { pagePath = new DependencyRouteConstraint<IsPageConstraint>() });
Stop! What is that DependencyRouteConstraint thing appeared in mapping? Well, thats what does the trick.
4. DependencyRouteConstraint<TConstraint> class
This is just another generic implementation of IRouteConstraint which takes the "real" IRouteConstraint (IsPageConstraint) and resolves it (the given TConstraint) only when Match() method called. It uses dependency injection so our IsPageConstraint instance has all actual dependencies injected!
Our DependencyRouteConstraint then just calls the dependentConstraint.Match() providing all the parameters thus just delegating actual "matching" to the "real" IRouteConstraint.
Note: this class actually has the dependency on ServiceLocator.
Summary
That way we have:
Our Route clear and clean;
The only class that has a dependency on Service Locator is DependencyRouteConstraint;
Any custom IRouteConstraint uses dependency injection whenever needed;
???
PROFIT!
Hope this helps.
So, the problem is:
Route must be defined beforehand, during Application startup
Route's responsibility is to map the incoming URL pattern to the right Controller/Action to perform some task on request. And visa versa - to generate links using that mapping data. Period. Everything else is "Single Responsibility Principle" violation which actually led to your problem.
But UoW dependencies (like NHibernate ISession, or EF ObjectContext) must be resolved at runtime.
And that is why I don't see the children of RouteBase class as a good place for some DB work dependency. It makes everything closely coupled and non-scalable. It is actually impossible to perform Dependency Injection.
From now (I guess there is some kind of already working system) you actually have just one more or less viable option that is:
To use Service Locator pattern: resolve your UoW instance right inside the GetRouteData method (use CommonServiceLocator backed by StructureMap IContainer). That is simple but not really nice thing because this way you get the dependency on static Service Locator itself in your Route.
With CSL you have to just call inside GetRouteData:
var uow = ServiceLocator.Current.GetService<IUnitOfWork>();
or with just StructureMap (without CSL facade):
var uow = ObjectFactory.GetInstance<IUnitOfWork>();
and you're done. Quick and dirty. And the keyword is "dirty" actually :)
Sure, there is much more flexible solution but it needs a few architectural changes. If you provide more details on exactly what data you get in your routes I can try to explain how we solved our Pages routing problem (using DI and custom IRouteConstraint).

Resources