I've a project using ASPNET MVC5 with WebApi2, OWIN and SimpleInjector as the IoC container.
I've read that if you're using OWIN you should get your HttpConfiguration, you'll create one rather than using GlobalConfiguration.
Like this in StartUp class, Configuration method:
var config = new HttpConfiguration();
config.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(container);
but with that I receive the error that I need a parameterless contructor, and if I use:
GlobalConfiguration.Configuration.DependencyResolver =
new SimpleInjectorWebApiDependencyResolver(container);
combined with (in SimpleInjectorInitializer):
container.RegisterWebApiControllers(GlobalConfiguration.Configuration,
AppDomain.CurrentDomain.GetAssemblies());
It works, but I read on the internet:
A common error in OWIN integration is use of the GlobalConfiguration.Configuration. In OWIN you create the configuration from scratch. You should not reference GlobalConfiguration.Configuration anywhere when using the OWIN integration.
Am I doing it OK for the OWIN and frameworks and technologies being used?
I've tried to follow this implementation of SimpleInjector with WebApi (there they're using MVC so I changed it a little). MVC 5 template (ASP.Net Identity 2.0) combined with Simple Injector
This is my snippet of the StartUp class now:
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
var container = SimpleInjectorInitializer.Initialize(app);
GlobalConfiguration.Configuration.DependencyResolver =
new SimpleInjectorWebApiDependencyResolver(container);
ConfigureAuth(app, container);
}
public void ConfigureAuth(IAppBuilder app, Container container)
{
// Added for IoC usage: See https://simpleinjector.codeplex.com/discussions/564822
app.Use(async (context, next) => {
using (container.BeginExecutionContextScope())
{
await next();
}
});
app.CreatePerOwinContext(() => container.GetInstance<ApplicationUserManager>());
// Enable the application to use a cookie to store information for the signed in user
// and to use a cookie to temporarily store information about a user logging in with a third party login provider
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
// Configure the application for OAuth based flow
PublicClientId = "self";
OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/Token"),
Provider = new ApplicationOAuthProvider(PublicClientId),
AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
// In production mode set AllowInsecureHttp = false
AllowInsecureHttp = true
};
// Enable the application to use bearer tokens to authenticate users
app.UseOAuthBearerTokens(OAuthOptions);
}
SimpleInjectorInitializer class
public static class SimpleInjectorInitializer
{
public static Container Initialize(IAppBuilder app)
{
var container = GetInitializeContainer(app);
container.Verify();
return container;
}
public static Container GetInitializeContainer(IAppBuilder app)
{
var container = new SimpleInjector.Container();
container.Options.DefaultScopedLifestyle = new WebApiRequestLifestyle();
container.RegisterSingleton<IAppBuilder>(app);
#region Webapi Registration
// IoC for ASP.NET Identity
container.RegisterWebApiRequest<ApplicationUserManager>();
container.RegisterWebApiRequest<ApplicationDbContext>(() => new ApplicationDbContext(ConfigurationManager.ConnectionStrings["orgIdentityConnectionString"].ConnectionString));
container.RegisterWebApiRequest<IUserStore<ApplicationUser>>(() => new UserStore<ApplicationUser>(container.GetInstance<ApplicationDbContext>()));
container.RegisterInitializer<ApplicationUserManager>(manager => InitializeUserManager(manager, app));
// Setup for ISecureDataFormat
container.RegisterWebApiRequest<ISecureDataFormat<AuthenticationTicket>, SecureDataFormat<AuthenticationTicket>>();
container.RegisterWebApiRequest<ITextEncoder, Base64UrlTextEncoder>();
container.RegisterWebApiRequest<IDataSerializer<AuthenticationTicket>, TicketSerializer>();
container.RegisterWebApiRequest<IDataProtector>(() => new Microsoft.Owin.Security.DataProtection.DpapiDataProtectionProvider().Create("ASP.NET Identity"));
#endregion
container.RegisterWebApiRequest<IAuthenticationManager>(() =>
AdvancedExtensions.IsVerifying(container)
? new OwinContext(new Dictionary<string, object>()).Authentication
: HttpContext.Current.GetOwinContext().Authentication);
// The initialization runs all the map creation once so it is then done when you come to do your mapping.
// You can create a map whenever you want, but this will slow your code down as the mapping creation involves reflection.
Mapper.Initialize(config =>
{
config.ConstructServicesUsing(container.GetInstance);
config.AddProfile(new WebApiAutomapperProfile());
config.AddGlobalIgnore("Errors");
config.AddGlobalIgnore("IsModelValid");
config.AddGlobalIgnore("BaseValidator");
config.AddGlobalIgnore("AuditInformation");
});
var profiles = Assembly.GetExecutingAssembly()
.GetTypes()
.Where(x => typeof(AutoMapper.Profile).IsAssignableFrom(x));
var config2 = new MapperConfiguration(cfg =>
{
foreach (var profile in profiles)
{
cfg.AddProfile(Activator.CreateInstance(profile) as AutoMapper.Profile);
}
});
container.RegisterSingleton<MapperConfiguration>(config2);
container.Register<IMapper>(() => config2.CreateMapper(container.GetInstance));
#region MyStuff Registrations
container.Register(typeof(IRepository<>), typeof(orgRepository<>), Lifestyle.Scoped);
container.Register(typeof(IDatabaseFactory<>), typeof(DatabaseFactory<>), Lifestyle.Scoped);
var orgCatalogRegistration = Lifestyle.Scoped.CreateRegistration<Catalog>(container);
container.AddRegistration(typeof(IPublicCatalog), orgCatalogRegistration);
container.AddRegistration(typeof(IPrivateCatalog), orgCatalogRegistration);
#endregion
**// TODO: A common error in OWIN integration is use of the GlobalConfiguration.Configuration. In OWIN you create the configuration from scratch. You should not reference GlobalConfiguration.Configuration anywhere when using the OWIN integration.**
//Is the following line OK?
container.RegisterWebApiControllers(GlobalConfiguration.Configuration, AppDomain.CurrentDomain.GetAssemblies());
return container;
}
private static void InitializeUserManager(ApplicationUserManager manager, IAppBuilder app)
{
manager.UserValidator = new UserValidator<ApplicationUser>(manager)
{
AllowOnlyAlphanumericUserNames = false,
RequireUniqueEmail = true
};
//Configure validation logic for passwords
manager.PasswordValidator = new PasswordValidator()
{
RequiredLength = 6,
RequireNonLetterOrDigit = false,
RequireDigit = true,
RequireLowercase = true,
RequireUppercase = true,
};
var dataProtectionProvider =
app.GetDataProtectionProvider();
if (dataProtectionProvider != null)
{
manager.UserTokenProvider =
new DataProtectorTokenProvider<ApplicationUser>(
dataProtectionProvider.Create("ASP.NET Identity"));
}
}
}
}
If you take a look at the same page you got that quote from, you'll see you have to register the Web API configuration into OWIN's IAppBuilder
as follows:
app.UseWebApi(config);