Sitecore.Services.Client
I am currently working on a very unique app. It’s not a traditional Sitecore architecture. Very far from it actually. Data driven, lots of client side renderings over raw data (JSON), dynamically loaded content fragments, and topped with personalization, analytics, and Sitecore playing content as a service role. Very cool I must say. Long story short, we are using Sitecore.Services.Client
(entity services) as our main data delivery mechanism which means we are using Web API.
Dependency Injection
When you add DI to Sitecore MVC you normally overwrite the controller factory. You can even chain factories to let the default ones run if yours can’t handle it. I blogged about the chaining technique before. It’s a little different with Web API though.
Our DI container of choice for this implementation is SimpleInjector
and here’s the code that we run during initialize
for MVC and Web API:
var container = new Container(); // ...registrations container.RegisterWebApiControllers(GlobalConfiguration.Configuration); container.RegisterMvcControllers(Assembly.Load("My.Assembly.Web")); // ...registrations // WebApi GlobalConfiguration.Configuration.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(container); // MVC DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));
Analytics Dashboard
We haven’t noticed it right away but our analytics dashboard was blank:
500
Looking under the hood we found these two:
Nothing in the log files but if you use one of those URLs directly you might see this:
Workaround
The workaround is actually very simple. Just need to tell SimpleInjector how to create the AnalyticsDataController
:
var container = new Container(); // ... container.Register(typeof(AnalyticsDataController) ,() => new AnalyticsDataController()); // ... GlobalConfiguration.Configuration.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(container);
After that:
Sitecore.Services.SecurityPolicy
One more important note. SSC controllers have a global SecurityPolicy
. This is technically a Web API filter that will apply to all SSC controllers – your own and Sitecore’s built-in. If you overwrite it with something application-specific, make sure you account for built-in controllers. We have it like this:
public class AuthorizedUsersOnlyPolicy: Sitecore.Services.Infrastructure.Web.Http.Security.ServicesOnPolicy { public override bool IsAuthorised(HttpActionContext actionContext) { var user = Sitecore.Context.User; return user.IsAdministrator || OurOwnHelper.UserCanBeTrusted(Sitecore.Context.User); } }
Thoughts
It would be nice if:
- Built-in Web API controllers were DI-ready and did not have multiple constructors
- Built-in Web API controllers had their own policy that wouldn’t be conflicting with the “global” application specific policy. I understand that we can have extra filters (and we do use them) but more isolation wouldn’t hurt.
@csteeg mentioned on twitter that he was dealing with some of it as well and shared a link.
Your thoughts? Maybe I’m missing something?
[su_divider][/su_divider]
UPDATE: @KevinObee suggested that I shouldn’t be using the global SecurityPolicy
for what I am trying to accomplish here. Instead, the recommendation is to use one of the built-in policies and then add application-specific filters to our own SSC controllers. Also, if you like me would like to know about what other SSC controllers there are in Sitecore, try Sitecore.Glimpse (also from Kevin)
Pingback: Safe Dependency Injection for MVC and WebApi within Sitecore | Sean Holmesby
Hi Pavel,
If we are not using dependancy injection, can you please provide code snippet for that case.
I am not sure where you’re getting your information, but great topic. I needs to spend some time learning much more or understanding more. Thanks for fantastic info I was looking for this information for my mission.|