ApiControllers在ASPNET MVC 5中使用WebApi和OWIN以及SimpleInjector进行注册

时间:2016-09-02 02:51:43

标签: asp.net-mvc asp.net-web-api inversion-of-control owin simple-injector

我使用ASPNET MVC5,WebApi2,OWIN和SimpleInjector作为IoC容器的项目。

我已经读过,如果您使用OWIN,您应该获得HttpConfiguration,您将创建一个而不是使用GlobalConfiguration。

StartUp 类中,如配置方法:

var config = new HttpConfiguration();
config.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(container);

但是我收到错误,我需要一个无参数的构造函数,如果我使用:

GlobalConfiguration.Configuration.DependencyResolver = 
    new SimpleInjectorWebApiDependencyResolver(container);

结合(在SimpleInjectorInitializer中):

container.RegisterWebApiControllers(GlobalConfiguration.Configuration,
    AppDomain.CurrentDomain.GetAssemblies());

它有效,但我看了on the internet

  

OWIN集成中的常见错误是使用GlobalConfiguration.Configuration。在OWIN中,您可以从头开始创建配置。使用OWIN集成时,不应在任何地方引用GlobalConfiguration.Configuration。

我是否正在使用OWIN以及正在使用的框架和技术?

我已经尝试使用WebApi跟踪SimpleInjector的这种实现(他们使用MVC,所以我稍微改了一下)。 MVC 5 template (ASP.Net Identity 2.0) combined with Simple Injector

这是我现在的StartUp课程片段:

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类

    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"));
            }
        }
    }
}

1 个答案:

答案 0 :(得分:0)

如果您查看引用的same page,您将看到必须将Web API配置注册到OWIN的IAppBuilder中,如下所示:< / p>

app.UseWebApi(config);