具有autofac的N层Web API应用程序

时间:2018-07-17 20:55:23

标签: c# asp.net-mvc asp.net-web-api dependency-injection asp.net-identity

我使用Autofac依赖注入开发了aspnet webapi应用,遇到了一个麻烦。

我创建了模型订单,模型存储库和工作单元

public class Order
    {
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int Id { get; set; }
        public string UserId { get; set; }
        public int ServiceId { get; set; }
        public string Header { get; set; }
        public string Description { get; set; }
        public string City { get; set; }
        public string Address { get; set; }
        public int Price { get; set; }
        public string Name { get; set; }
        public string PhoneNumber { get; set; }
        public DateTime CompletedOn { get; set; }
        public DateTime CreatedAt { get; set; }
        public DateTime UpdatedAt { get; set; }
    }

OrderRepository.cs

public class OrderRepository : IRepository<Order>
    {
        private ApplicationContext database;

        public OrderRepository(ApplicationContext database)
        {
            this.database = database;
        }

        public void Create(Order item)
        {
            database.Orders.Add(item);
        }

        public void Delete(int id)
        {
            var order = database.Orders.Find(id);
            if (order != null)
            {
                database.Orders.Remove(order);
            }
        }

        public Order Get(int id)
        {
            return database.Orders.Find(id);
        }

        public IEnumerable<Order> GetList()
        {
            return database.Orders;
        }

        public void Update(Order item)
        {
            database.Entry(item).State = EntityState.Modified;
        }
    }

UnitOfWork.cs

public class UnitOfWork : IUnitOfWork
    {
        private ApplicationContext database;
        private OrderRepository orderRepository;

        private bool disposed = false;

        public IRepository<Order> Orders
        {
            get
            {
                if (orderRepository == null)
                {
                    orderRepository = new OrderRepository(database);
                }

                return orderRepository;
            }
        }

        public UnitOfWork(ApplicationContext database)
        {
            this.database = database;
        }

        public async Task SaveAsync()
        {
            await database.SaveChangesAsync();
        }

        public virtual void Dispose(bool disposing)
        {
            if (!this.disposed)
            {
                if (disposing)
                {
                    database.Dispose();
                }
                this.disposed = true;
            }
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
    }

然后我制作了 OrderManager

public class OrderManager : IOrderManager
    {
        IUnitOfWork database;

        public OrderManager(IUnitOfWork database)
        {
            this.database = database;
        }

        public void CreateOrder(OrderViewModel order)
        {
            database.Orders.Create(new Order
            {
                UserId = order.UserId,
                Header = order.Header,
                Description = order.Description,
                City = order.City,
                Address = order.Address,
                Price = order.Price,
                Name = order.Name,
                PhoneNumber = order.PhoneNumber,
                CompletedOn = order.CompletedOn,
                CreatedAt = order.CreatedAt,
                UpdatedAt = order.UpdatedAt
            });
        }

        public Order GetOrder(int id)
        {
            return database.Orders.Get(id);
        }

        public IEnumerable<Order> GetOrders()
        {
            return database.Orders.GetList();
        }
    }

然后我尝试进行注入,我认为这是我写的错误。

public static void ConfigureContainer()
        {
            var builder = new ContainerBuilder();

            builder.RegisterControllers(typeof(User).Assembly);

            builder.RegisterType<ApplicationContext>().AsSelf().InstancePerRequest().WithParameter("connectionString", "DefaultConnection");
            builder.RegisterType<ApplicationUserManager>().AsSelf().InstancePerRequest();
            builder.Register(c => new UnitOfWork(c.Resolve<ApplicationContext>())).AsImplementedInterfaces().InstancePerRequest();
            builder.RegisterType<OrderManager>().AsSelf().InstancePerRequest();
            //builder.RegisterType<UnitOfWork>().As<IUnitOfWork>().WithParameter("database", new ApplicationContext("DefaultConnection")); ;
            builder.RegisterType<UserStore<User>>().As<IUserStore<User>>().InstancePerLifetimeScope();
            builder.Register(c => new UserStore<User>(c.Resolve<ApplicationContext>())).AsImplementedInterfaces().InstancePerRequest();
            builder.RegisterType<RoleStore<IdentityRole>>().As<IRoleStore<IdentityRole, string>>().InstancePerLifetimeScope();
            //builder.Register(c => HttpContext.Current.GetOwinContext().Authentication).As<IAuthenticationManager>();

            builder.Register(c => new IdentityFactoryOptions<ApplicationUserManager>
            {
                DataProtectionProvider = new Microsoft.Owin.Security.DataProtection.DpapiDataProtectionProvider("ASP.NET Identity​")
            });

            var container = builder.Build();

            DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
        }

错误出现的地方

 protected OrderManager orderManager;

        public ValuesController()
        { }

        public ValuesController(OrderManager orderManager)
        {
            this.orderManager = orderManager;
        }

        public OrderManager OrderManager
        {
            get
            {
                return orderManager;
            }
            set
            {
                orderManager = value;
            }
        }

public OrderViewModel Get(int id)
        {
            var order = OrderManager.GetOrder(id);

            var orderViewModel = new OrderViewModel
            {
                Header = order.Header,
                Description = order.Description,
            };

            return orderViewModel;
        }

当我获得订单时,该站点掉落,因为OrderManager为null。我想我的DI实现中存在问题,但我仍然不知道如何解决。

Error

1 个答案:

答案 0 :(得分:0)

我认为您的设置代码不正确。在ConfigureCOntainer中,执行此操作

 public static void ConfigureContainer()
        {
            var builder = new ContainerBuilder();

            // Get your HttpConfiguration.
            var config = GlobalConfiguration.Configuration;

            // Register your Web API controllers.
            builder.RegisterApiControllers(Assembly.GetExecutingAssembly());

            // OPTIONAL: Register the Autofac filter provider.
            builder.RegisterWebApiFilterProvider(config);

            // OPTIONAL: Register the Autofac model binder provider.
            builder.RegisterWebApiModelBinderProvider();


            builder.RegisterType<ApplicationContext>().AsSelf().InstancePerRequest().WithParameter("connectionString", "DefaultConnectionString");
            builder.Register(c => new UnitOfWork(c.Resolve<ApplicationContext>())).AsImplementedInterfaces().InstancePerRequest();
            builder.RegisterType<OrderManager>().AsSelf().InstancePerRequest();



            // Set the dependency resolver to be Autofac.
            var container = builder.Build();
            config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
        }

并且应该在其他API配置代码(例如

)之前调用该方法
  public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // Web API configuration and services
            ConfigureContainer();

            // Web API routes
            config.MapHttpAttributeRoutes();

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


        }


        public static void ConfigureContainer()
        {
            var builder = new ContainerBuilder();

            // Get your HttpConfiguration.
            var config = GlobalConfiguration.Configuration;

            // Register your Web API controllers.
            builder.RegisterApiControllers(Assembly.GetExecutingAssembly());

            // OPTIONAL: Register the Autofac filter provider.
            builder.RegisterWebApiFilterProvider(config);

            // OPTIONAL: Register the Autofac model binder provider.
            builder.RegisterWebApiModelBinderProvider();


            builder.RegisterType<ApplicationContext>().AsSelf().InstancePerRequest().WithParameter("connectionString", "DefaultConnectionString");
            builder.Register(c => new UnitOfWork(c.Resolve<ApplicationContext>())).AsImplementedInterfaces().InstancePerRequest();
            builder.RegisterType<OrderManager>().AsSelf().InstancePerRequest();



            // Set the dependency resolver to be Autofac.
            var container = builder.Build();
            config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
        }
    }

我可以看到实例是在Web Api控制器中正确创建的

enter image description here

控制器代码为

public class ValuesController : ApiController
    {
        public ValuesController(OrderManager orderManager)
        {
            this.OrderManager = orderManager;
        }

        public OrderManager OrderManager { get; set; }


        [Route("orders")]
        public IHttpActionResult GetAll()
        {
            return Ok("Received");
        }

        [Route("orders/{id}")]
        public OrderViewModel Get(int id)
        {
            var order = OrderManager.GetOrder(id);

            var orderViewModel = new OrderViewModel
            {
                Header = order.Header,
                Description = order.Description,
            };

            return orderViewModel;
        }