Sitecore DI with Unity - sitecore

I'm trying to setup a brand new Sitecore 7.2 website and I'm looking to integrate MVC 5, Glass Mapper and Microsoft Unity as a DI container and Sitecore doesn't want to play very nice.
My scenario is this:
Got a Web project called PoC.Quotes.Web - this will contain only CSS, HTML and any other assets, no controllers
Got a class library project called PoC.Quotes.Controllers - this only contains controllers
Got a class library project called PoC.Quotes.DataLayer - this contain a interface ISitecoreRepository and it's concrete implementation SitecoreRepository
The SitecoreRepository class has a constructor that receives 1 single parameter, the Glass Mapper Context, and one of my controllers receives 1 single parameter in the constructor...the ISitecoreRepository.
Sitecore repository class:
public class SitecoreRepository : ISitecoreRepository
{
ISitecoreContext sitecoreContext = null;
public SitecoreRepository(ISitecoreContext context)
{
this.sitecoreContext = context;
}
}
Controller class:
public class HomeController : Controller
{
private ISitecoreRepository _repository;
public HomeController(ISitecoreRepository repository)
{
this._repository = repository;
}
}
Every time I run the project Sitecore throws an error saying that it cannot create a controller of type (PoC.Quotes.Controllers.HomeController, PoC.Quotes.Controllers). I guess it shows the fully qualified name because that's how I set it up in the controller rendering.
First problem is the controller constructor parameter. I took it out and use this statement to get the instance for the repository:
System.Web.Mvc.DependencyResolver.Current.GetService<ISitecoreRepository>();
The result is null, because the class SitecoreRepository is only having 1 constructor with 1 parameter and it won't get instantiated. Once I get that parameter out of the question too, then all works great.
However, to me this kinda defies the purpose of having a DI container.
I've tried looking at Castle Windsor, but although there is more documentation online, nothing works as I'm getting similar issues.
It is a bit annoying because if I run a similar test in a basic MVC 5 app (I did that just to be sure I'm not going mad), all works fine in less than 5 minutes.
Any ideas?
Edit:
In an interesting twist, after a few good hours spent on this issue, I've noticed that actually either Unity or Windsor containers work fine with one limitation...a big one.
In my controller rendering I've set the controller property as the fully qualified name of the controller:
PoC.Quotes.Controllers.HomeController, PoC.Quotes.Controllers
However, if I go in Sitecore and change that property to just Home, by magic all is good. I've even tried the interim version of using PoC.Quotes.Controllers.Home but still get an error, a different one mind you.
Not sure if I'm doing something wrong but it feels a bit odd.
Any ideas how to get this fixed?

While I can't tell how your registrations are configured, it sounds like you might be better off with a controller factory. The example is Windsor but you could easily swap in Unity. So that you're not modifying the Global.asax, you can also use WebActivatorEx to wire up the bootstrapping startup.
Bootstrapper
[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(Site.Website.Cms.WindsorConfig), "RegisterComponents")]`
[assembly: WebActivatorEx.ApplicationShutdownMethod(typeof(Site.Website.Cms.WindsorConfig), "ReleaseComponents")]
/// <summary>
/// Provides a bootstrapping and resolving hook for dependency resolution for MVC, Web API, and service locator.
/// </summary>
public static class WindsorConfig
{
private static Lazy<IWindsorContainer> _container;
static WindsorConfig()
{
_container = new Lazy<IWindsorContainer>(() => BuildContainer());
}
public static IWindsorContainer WindsorContainer
{
get
{
return _container.Value;
}
}
/// <summary>
/// Generates and configures the container when the application is started.
/// </summary>
public static void RegisterComponents()
{
ControllerBuilder.Current.SetControllerFactory(new WindsorControllerFactory(WindsorContainer));
GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerActivator), new WindsorControllerActivator(WindsorContainer));
}
/// <summary>
/// Disposes of the container when the application is shut down.
/// </summary>
public static void ReleaseComponents()
{
WindsorContainer.Dispose();
}
}
Controller Factory
/// <summary>
/// Provides controller dependency resolving for ASP.NET MVC controllers.
/// </summary>
public class WindsorControllerFactory : DefaultControllerFactory
{
private readonly IWindsorContainer _container;
public WindsorControllerFactory(IWindsorContainer container)
{
if (container == null) throw new ArgumentNullException("container");
this._container = container;
}
public override void ReleaseController(IController controller)
{
this._container.Release(controller);
}
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
if (controllerType == null)
{
throw new HttpException(404, string.Format("The controller for path '{0}' could not be found.", requestContext.HttpContext.Request.Path));
}
return (IController)this._container.Resolve(controllerType);
}
}

Spent a considerable amount of time on this and managed to come up with a solution. It was a bit long to write in here so I've put it on a blog post http://agooddayforscience.blogspot.co.uk/2015/10/sitecore-multi-tenancy-and-di-containers.html
Basically it wasn't an issue with Unity or other DI container, it was around how Sitecore handles fully qualified names. Yes, I know that ideally you don't want to use those but to follow the MVC pattern, but I've explained more in the blog post around why use fully qualified names.
As a high level explanation the problem resides in 2 Sitecore classes ControllerRunner and SitecoreControllerFactory. Both classes contain some methods that identify the fully qualified name and use reflection to call the parameter-less constructor to instantiate a new instance. The fix I've applied overrides these methods to call the controller factory regardless.
Thanks for all the help provided.
Andrei

Related

The controller for path '/api/sitecore/TestForms/TestFormsAPI' was not found or does not implement IController

I am creating a controller and inheriting GlassController, I am trying to call controller action method using ajax and the URL requested is '/api/sitecore/TestForms/TestFormsAPI' and it throws an exception saying "The controller for path '/api/sitecore/TestForms/TestFormsAPI' was not found or does not implement IController."
Attached are the screen shot of my code and exception:
Can anyone suggest what could be the issue?
Sitecore has a different way of routing. This may be conflicting with the default Sitecore Client route. Implement this using custom route. Follow this link - https://kb.sitecore.net/articles/700677
I shall also suggest to use Route attribute instead and this is how it can be done. (I havent tested following code)
[RoutePrefix("api/Custom")]
public class MyCustomController : ApiController
{
ICustomRepository _customRepository;
public MyCustomController(ICustomRepository _customRepository
{
_customRepository= customRepository
}
[Route("GetCustomMethod")]
[HttpPost]
public IHttpActionResult GetCustomMethod()
{
......
......
return Ok(results);
}
}
Had the custom route registered as in the article in sandy's answer (https://kb.sitecore.net/articles/700677), however it kept crashing with the same error because I included "Controller" when specifying the controller name, removing it fixed the issue (see https://stackoverflow.com/a/41901846/712700).

Need help testing Binding in Windows Phone 8

I hope someone has already faced and solved this issue, and can point me to the correct direction.
So I have rest of my unit tests working: Core.Tests has tests for ViewModels to see they are working properly. Now I would like to set up a test project for Phone.Tests that would only test out the binding. So suppose on the login page, something get's entered into the username text box, and that value should be updated in ViewModel and vice-versa.
As a testing framework, I am using WP Toolkit Test framework, and not MS one; WP Toolkit framework runs on the phone itself, meaning it has access to the UI thread.
In theory a test is supposed to look like following:
[TestMethod]
[Asynchronous]
public void Username_Update_View_Should_Update_Model()
{
const string testUsername = "Testing";
var usernameTextBox = GetUiElement<PhoneTextBox>("UsernamePhoneTextBox");
// initial value
Assert.AreEqual(null, _viewModel.Authorization.Username, "Default value should be blank");
//
usernameTextBox.Text = testUsername;
//
Assert.AreEqual(testUsername, _viewModel.Authorization.Username, "Binding not set for {0}", "Username");
}
private T GetUiElement<T>(string name) where T : UIElement
{
return (T)_view.FindName(name);
}
Now, I need to somehow create the view in [TestInitialize] method, and this is what I think I have setup wrong.
I have tried creating the ViewModel manually; then I created the View manually, and binded both DataContext and ViewModel (just to be on safe side) to created viewModel.
At this point, I am expecting changing one property on any one should update the other.
Of-course the error is my test fails. I can't figure out if I should be looking at a custom presenter (all the examples seem to be for ios, droid.) I also tried the following:
public class TestAppStart : MvxNavigatingObject, IMvxAppStart
{
public void Start(object hint = null)
{
ShowViewModel<UserLoginViewModel>();
}
}
and then on my testInitialize I thought I could start it, but I guess I need to find RegisterAppStart and once that's done, try to get the view back from RootFrame.
There must be an easier way... anyone??
Thanks in advance.
Edited: I have got this following as Base Test
public abstract class BaseTest
{
private IMvxIoCProvider _ioc;
protected IMvxIoCProvider Ioc
{
get
{
return _ioc;
}
}
public void Setup()
{
ClearAll();
}
protected virtual void ClearAll()
{
MvxSingleton.ClearAllSingletons();
_ioc = MvxSimpleIoCContainer.Initialize();
_ioc.RegisterSingleton(_ioc);
_ioc.RegisterSingleton((IMvxTrace)new DebugTrace());
InitialiseSingletonCache();
InitialiseMvxSettings();
MvxTrace.Initialize();
AdditionalSetup();
}
private static void InitialiseSingletonCache()
{
MvxSingletonCache.Initialize();
}
protected virtual void InitialiseMvxSettings()
{
_ioc.RegisterSingleton((IMvxSettings)new MvxSettings());
}
protected virtual void AdditionalSetup()
{
_ioc.RegisterSingleton(Mock.Of<ISettings>);
_ioc.RegisterSingleton<IApplicationData>(() => new ApplicationData());
_ioc.RegisterSingleton<IPlatformSpecific>(() => new PlatformSpecific());
_ioc.RegisterSingleton<IValidatorFactory>(() => new ValidatorFactory());
//
_ioc.RegisterType<IMvxMessenger, MvxMessengerHub>();
}
}
On my TestClass initialize, I call base.Setup(), which does setup except the ViewDispatcher. Unfortunately I can't figure out how to use that dispatcher:
I guess really the question I am asking is: how do I get a View through MvvmCross.
PS: I am actually surprised that most don't test the bindings; isn't it where the most amount of mistakes is likely to happen? I am pretty sure the project compiles even if I had bad binding :) scary kind of reminds me of early asp days.
PS: I have actually got another testProject that tests the ViewModels; on that testProject I have managed to hookup following the guidelines at
http://blog.fire-development.com/2013/06/29/mvvmcross-unit-testing-with-autofixture/
Which works beautifully; and also uses autoFixture, NSubstitute and xUnit: and I can't use any of them in Phone Test project.
From my experience, testing the bindings themselves is pretty unusual - most developers stop their testing at the ViewModel and ValueConverter level.
However, if you want to test the bindings, then this should be possible. I suspect the only problem in your current tests is that you haven't initialised any of the MvvmCross infrastructure and so MvxViewModel isn't able to propagate INotifyPropertyChanged events.
If you want to initialise this part of the MvvmCross infrastructure, then be sure to initialise at least:
the MvvmCross IoC container
the MvvmCross main thread dispatcher
This is similar to what is done in the unit tests in the N=29 video - see https://github.com/MvvmCross/NPlus1DaysOfMvvmCross/blob/master/N-29-TipCalcTest/TipCalcTest.Tests/FirstViewModelTests.cs#L57
For your app, you can do this using something like:
public static class MiniSetup
{
public static readonly MiniSetup Instance = new MiniSetup();
private MiniSetup()
{
}
public void EnsureInitialized(Context applicationContext)
{
if (MvxSimpleIoCContainer.Instance != null)
return;
var ioc = MvxSimpleIoCContainer.Initialize();
ioc.RegisterSingleton<IMvxTrace>(new MvxDebugOnlyTrace());
MvxTrace.Initialize();
var mockDispatcher = new SimpleDispatcher();
Ioc.RegisterSingleton<IMvxMainThreadDispatcher>(simpleDispatcher);
}
}
where SimpleDispatcher is something like:
public class SimpleDispatcher
: MvxMainThreadDispatcher
{
public readonly List<MvxViewModelRequest> Requests = new List<MvxViewModelRequest>();
public bool RequestMainThreadAction(Action action)
{
action();
return true;
}
}
If you want further MvvmCross functionality available (e.g. ShowViewModel navigation), then you'll need to provide further services - e.g. things like IMvxViewDispatcher - as the number of these increases, you might be better off just running through a full MvxSetup process (like your main app's Setup does)

Getting rid of 'new' operators for subcomponents objects

I've been reading Misko Hevery's classic articles about Dependency injection, and basically 'separating the object graph creation code from the code logic'.
The main idea seems to be "get rid of the 'new' operators", put them in dedicated objects ('Factories') and inject everything you depend on."
Now, I can't seem to wrap my head about how to make this works with objects that are composed of several other components, and whose job is to isolate those components to the outerworld.
Lame example
A View class to represent a combination of a few fields, and a button. All the components depend on a graphical ui context, but you want to hide it behind the interfaces of each sub-component.
So something like (in pseudo-code, language does not really matter I guess):
class CustomView() {
public CustomView(UIContext ui) {
this.ui = ui
}
public void start() {
this.field = new Field(this.ui);
this.button = new Button(this.ui, "ClickMe");
this.button.addEventListener(function () {
if (field.getText().isEmtpy()) {
alert("Field should not be empty");
} else {
this.fireValueEntered(this.field.getText());
}
});
}
// The interface of this component is that callers
// subscribe to "addValueEnteredListener"..)
public void addValueEnteredListener(Callback ...) {
}
public void fireValueEnteredListener(text) {
// Would call each listeners in turn
}
}
The callers would do something like :
// Assuming a UIContext comes from somewhere...
ui = // Wherever you get UI Context from ?
v = new CustomView(ui);
v.addValueEnteredListener(function (text) {
// whatever...
});
Now, this code has three 'new' operators, and I'm not sure which one Misko (and other DI proponents) are advocating to rid off, or how.
Getting rid of new Field() and new Button()
Just Inject it
I don't think the idea here is to actually inject the instances of Field and Button , which could be done this way :
class CustomView() {
public CustomView(Field field, Button button) {
this.field = field;
this.button = button;
}
public void start() {
this.button.addEventListener(function () {
if (field.getText().isEmtpy()) {
alert("Field should not be empty");
} else {
this.fireValueEntered(this.field.getText());
}
});
}
// ... etc ...
This makes the code of the component lighter, surely, and it actually hides the notion of UI, so the MetaForm component has clearly been improved in terms of readability and testability.
However, the burden is now on the client to create those things :
// Assuming a UIContext comes from somewhere...
ui = // wherever ui gets injected from
form = new Form(ui);
button = new Button(ui);
v = new CustomView(form, button);
v.addValueEnteredListener(function (text) {
// whatever...
});
That sounds really troubling to me, espacially since the client know has to all the inners of the class, which sounds silly.
Mama knows, inject her instead
What the articles seems to advocate is instead injecting a Factory to create the components elements.
class CustomView() {
public CustomView(Factory factory) {
this.factory = factory;
}
public void start() {
this.field = factory.createField();
this.button = factory.createButton();
this.button.addEventListener(function () {
if (field.getText().isEmtpy()) {
alert("Field should not be empty");
} else {
this.fireValueEntered(this.field.getText());
}
});
}
// ... etc ...
And then everything gets nice for the caller, because its just has to get the factory from somewhere (and this factory will be the only to know about the UI context, so hurray for decoupling.)
// Assuming a UIContext comes from somewhere...
factory = // wherever factory gets injected from
v = new CustomView(factory);
v.addValueEnteredListener(function (text) {
// whatever...
});
A possible drawback is that when testing the MetaForm, you will typically have to use a 'Mock' Factory that ... create Mocks version of the Field & Button classes. But obviously there is another drawback ...
Yo' Factory so fat!!
How big will the Factory get ? If you follow the pattern rigorously, then every single frigging component you ever want to create in you application at runtime (wich is typically the case for UI, right) will have to get its own createXXXXX methods in at least one factory.
Because now you need :
Factory.createField to create the field
Factory.createButton to create the button
Factory.createMetaForm to create the field, the button and the MetaForm when a client (say the MetaEditPage wants to use one)
And obviously a Factory.createMetaEditPage for the client..
... and its turtles all the way.
I can see some strategies to simplify this :
As much as possible, separate the parts of the graph that are created at "startup" time from the parts that are created at runtime (using an DI framework like Spring for the former, and factories for the latter)
Layer the factories, or collocate related objects in the same factories (a UIWidgetFactory would make sense for Field and Button, but where would you put the other ones ? In a Factory linked to the Application ? To some other logical level ?)
I can almost hear all the jokes from C guys that no Java app can do anything without calling a ApplicationProcessFactoryCreator.createFactory().createProcess().startApplication() chain of nonsense...
So my questions are :
I am completely missing a point here ?
If not, which strategy would you suggest to make the things bearable ?
Addendum : why I'm not sure dependency injection would help
Assume I decide to use dependency injection, with a guice-like framework. I would end up writing code like this :
class CustomView
#Inject
private Field fiedl;
#Inject
private Button button;
public void start() {
this.button.addEventListener(....
// etc...
And then what ?
How would my "Composition Root" make use of that ? I can certainely not configure a "singleton" (with a lowercase 's', as in 'the single instance of a class) for the Field and the Button (since I want to create as many instances of them as instances of MetaForm ?
It would not make sense to use a Provider, since my problem is not which instance of buttons I want to create, but just that I want to create it lately, with some configuration (for example its text) that only makes sense for this form.
To me DI is not going to help because I am new-ing parts of my component rather than Dependencies. And I suppose I could turn any subcomponent into a dependency, and let a framework inject them. It's just that injecting subcomponents looks really artificial and couter-intuitive to me, in this case... so again, I must be missing something ;)
Edit
In particular, my issue is that I can't seem to understand how you would test the following scenario :
"when I click on the button, if the Field is empty, there should be an error".
This is doable if I inject the button, so that I can call its "fireClicked" event manually - but it feels a bit silly.
The alternative is to just do view.getButton().fireClicked() , but that looks a bit ugly...
Well, you can use some DI Framework (Spring or Guice) and get rid of factory method completely. Just put some annotation on the field/constructor/set method and DI Framework will do the work. At unit-test use mock framework.
How about not being overly obsessed with the "no new" dogma ?
My take is that DI works well for - well you know, Dependencies, or Delegates. Your example is about composition and IMHO it absolutely makes sense that the owning entity (your CustomView) creates explicitly its components. After all, the clients of the composite do not even have to know that these components exist, how they are initialized or how you use them.

Reference model in template beyond request / page scope, in Play! 1.2.4

I came across at this thread, does anybody know how to do this in Play! 1.2.4? Thanks.
The same effect is not quite possible, I think. You can of course reference classes in your Models package by using fully qualified names (models.YourModel) to access enumerations, for example.
Anything you add in the renderArgs scope in your controller will be available in the template, plus there are some implicit objects that are always in use (see Play framework documentation for full listing). For example the play.Play object contains all kinds of useful stuff.
With #Before and #With annotations you can set up a controller used by multiple other controllers to have objects "globally" available - see Interceptions.
Even better, create a super controller extending Controller. Afterwards, let all your controllers extends your SuperController.
class SuperController extends Controller {
#Before
public static function before() {
// Set global variables using renderArgs
}
}
class MyController extends SuperController {
public function myMethod() {
// Do whatever your method does.
}
}
Check out the documentation : http://www.playframework.org/documentation/1.2.4/controllers#result

using IProvideDynamicTestMethods for silverlight 4 unit tests

Has anyone had any lucking creating their custom test class and using the IProvideDynamicTestMethods interface? I have a case where I need to dynamically generate test methods and this seems to be what I need. I goal is to have test methods generated based on some files I am testing.
Jeff Wilcox mentions this as a new feature in SL3 ( http://www.jeff.wilcox.name/2008/09/rc0-new-test-features/ , see the dynamic test methods section), but I was unable to find any examples of this.
I don't know how to register my custom test class (it inherits from ITestClass). I looked at the SL4 unit testing source to see how the test class are discovered and I found the following in UnitTestFrameworkAssembly.cs source link
/// <summary>
/// Reflect and retrieve the test class metadata wrappers for
/// the test assembly.
/// </summary>
/// <returns>Returns a collection of test class metadata
/// interface objects.</returns>
public ICollection<ITestClass> GetTestClasses()
{
ICollection<Type> classes = ReflectionUtility.GetTypesWithAttribute(_assembly, ProviderAttributes.TestClass);
List<ITestClass> tests = new List<ITestClass>(classes.Count);
foreach (Type type in classes)
{
tests.Add(new TestClass(this, type));
}
return tests;
}
It looks like it will always use the built-in TestClass.
Am I missing something? I don't how to get the test framework to use my custom TestClass
Any pointers appreciated.
Thanks
It looks like the only way to set this up right now is to write your own UnitTestProvider for the test runner. The good thing is the code is available, so it's not too hard to do this.
You can either grab the code from the default Vstt from codeplex here and make any changes you you like to it. I'm still experimenting with this right now, so lets see how this goes. I got this idea by looking at this github project.
The key was to plug in your own provider, which was done in Raven.Tests.Silverlight.UnitTestProvider.Example/App.xaml.cs.
Hope this helps someone