autofac / Autofac.Owin

OWIN integration for Autofac
MIT License
23 stars 15 forks source link

owin autofac middleware and controller lifetime not same one #33

Open ZevFung opened 2 years ago

ZevFung commented 2 years ago

Describe the Bug

owin one request autofac middleware and controller lifetime not same one

UnitOfWorkManagerMiddleware

Dingtalk_20220824103418

TemplateService Dingtalk_20220824103612

Steps to Reproduce

Startup.css

 /// <summary>
    /// 
    /// </summary>
    public class Startup
    {
        /// <summary>
        /// 
        /// </summary>
        public Startup()
        {
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="app"></param>
        public void Configuration(IAppBuilder app)
        {
            HttpConfiguration config = new HttpConfiguration();

            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );

            config.Formatters.XmlFormatter.SupportedMediaTypes.Clear();
            config.Formatters.JsonFormatter.MediaTypeMappings.Add(new QueryStringMapping("datatype", "json", "application/json"));
            config.Formatters.JsonFormatter.SerializerSettings = new Newtonsoft.Json.JsonSerializerSettings()
            {
                NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore 
            };

            ConfigureAutofac(app, config);
            app.UseWebApi(config);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="appBuilder"></param>
        /// <param name="config"></param>
        private static void ConfigureAutofac(IAppBuilder appBuilder, HttpConfiguration config)
        {
            var builder = new ContainerBuilder();

            builder.RegisterApiControllers(Assembly.GetExecutingAssembly());

            #region SingleInstance

            var assemblyCore = Assembly.Load("Api");
            var assemblyCommon = Assembly.Load("Common");
            builder.RegisterAssemblyTypes(assemblyCore, assemblyCommon)
            .Where(t => t.GetCustomAttribute<SingleInstanceAttribute>() != null)
            .SingleInstance();

            builder.RegisterAssemblyTypes(assemblyCore, assemblyCommon)
            .Where(t => t.GetCustomAttribute<SingleInstanceAttribute>() != null)
            .AsImplementedInterfaces()
            .SingleInstance();
            #endregion

            #region Repository
            var assemblyRepository = Assembly.Load("Repository");
            builder.RegisterAssemblyTypes(assemblyRepository)
            .AsImplementedInterfaces()
            .InstancePerRequest();
            #endregion

            #region Service
            var assemblyServices = Assembly.Load("Services");
            builder.RegisterAssemblyTypes(assemblyServices)
            .AsImplementedInterfaces()
            .InstancePerRequest();
            #endregion

            builder.RegisterType<UnitOfWorkManagerMiddleware>().InstancePerRequest();

            var container = builder.Build();

            config.DependencyResolver = new AutofacWebApiDependencyResolver(container);

            appBuilder.UseAutofacMiddleware(container);

        }
    }

Middleware

/// <summary>
    /// 
    /// </summary>
    public class UnitOfWorkManagerMiddleware : OwinMiddleware
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="next"></param>
        /// <param name="unitOfWorkManager"></param>
        public UnitOfWorkManagerMiddleware(OwinMiddleware next, UnitOfWorkManagerCloud unitOfWorkManager, ITemplateRepository _templateRepository, ITemplateRepository _templateRepository2) : base(next)
        {
        }

        public override async Task Invoke(IOwinContext context)
        {
            try
            {
                await Next.Invoke(context);
            }
            finally
            {
                TransactionalAttribute.SetUnitOfWorkManager(null);
            }
        }
    }

Repository

    public class TemplateRepository : ITemplateRepository
    {
        readonly string aa = Guid.NewGuid().ToString();

        public TemplateRepository(UnitOfWorkManagerCloud uowm) : base(uowm)
        {
        }
    }

    public interface ITemplateRepository : IRepositoryCloud<TemplateEntity>
    {
    }
public class TemplateService : ITemplateService
    {
        private readonly ITemplateRepository _templateRepository;
        private readonly ITemplateRepository _templateRepository2;

        private readonly UnitOfWorkManagerCloud _uowm;

        public TemplateService(ITemplateRepository templateRepository,ITemplateRepository templateRepository2, UnitOfWorkManagerCloud uowm)
        {
            _templateRepository = templateRepository;
            _templateRepository2 = templateRepository2;

            _uowm = uowm;
            //TransactionalAttribute.SetUnitOfWorkManager(uowm);
        }
}
public class UnitOfWorkManagerCloud
    {
        readonly string aa = Guid.NewGuid().ToString();
        public UnitOfWorkManagerCloud()
        {
        }
    }

Expected Behavior

owin autofac middleware and controller lifetime

same one

Exception with Stack Trace

Put the exception with stack trace here.

Dependency Versions

Autofac: 6.4.0.0 Autofac.Integration.Owin: 7.0.0.0 Autofac.Integration.WebApi:6.1.1.0

Additional Info

Sample WindowsFormsApp7.zip

tillig commented 2 years ago

As much as we want to help folks, there isn't a large team of support people that can diagnose issues in complex codebases. It's really important to provide an absolutely minimal reproducible example, not in a zip or repo we have to work through.

I also see the zip is called WindowsFormsApp7.zip, which, from the name, indicates it's not a standard OWIN app. Try this as a super boiled down, stock app - no self hosting, no extras.

Once it's reduced to the minimum it should be easy enough to post here (not a zip file) and we're can probably check it out.

If you're not able to minimize the repro, you may end up waiting a very long time for us to unwind this. I'm honestly sorry that's the case, but we really are pretty strapped for time.