说明:抽象类BaseController 继承了Controller,里面我封装了常用的信息方法,所有的页面级Controller均继承BaseController,那么导致AutoFac提示错误,无法实例化。代码如下:
public abstract class BaseController : Controller { /// <summary> /// 身份认证上下文 /// </summary> protected IAuthenticationManager AuthenticationManager => HttpContext.GetOwinContext().Authentication; protected LoginInfo LoginInfo { get { if (!User.Identity.IsAuthenticated) return null; var userData = ((ClaimsIdentity)User.Identity).FindFirst(ClaimTypes.UserData); return userData == null ? null : JsonConvert.DeserializeObject<LoginInfo>(userData.Value); } } /// <summary> /// 登录创建身份认证信息,写入Cookie /// </summary> /// <param name="user"></param> public void CreateIdentity(LoginInfo user) { var loginUserJson = JsonConvert.SerializeObject(user); var claimsIdentity = new ClaimsIdentity(DefaultAuthenticationTypes.ApplicationCookie); var claims = new List<Claim> { new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()), new Claim(ClaimTypes.Name, user.NickName), new Claim(ClaimTypes.UserData, loginUserJson) }; claimsIdentity.AddClaims(claims); AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie); AuthenticationManager.SignIn(new AuthenticationProperties { IsPersistent = user.RememberMe }, claimsIdentity); } }
1 public class AccountController : BaseController 2 { 3 4 private readonly IService.Account.IUser _userService; 5 6 public AccountController(IService.Account.IUser userService) 7 { 8 _userService = userService; 9 } 10 }
/// <summary> /// 批量注入IOC依赖对象 /// </summary> private static void AutofacMvcRegister() { var builder = new ContainerBuilder(); //仓储模式注入 builder.RegisterGeneric(typeof(MongoRepository<,>)).As(typeof(IRepository<,>)).InstancePerLifetimeScope(); //DbContext注入 builder.RegisterType(typeof(MongoDbContext)).As(typeof(IMongoDbContext)).InstancePerLifetimeScope(); //批量注入IDependency接口实现对象 var assemblies = BuildManager.GetReferencedAssemblies().Cast<Assembly>().ToList(); var baseType = typeof(IDependency); //InstancePerLifetimeScope 保证生命周期基于请求 builder.RegisterAssemblyTypes(assemblies.ToArray()).Where(type => baseType.IsAssignableFrom(type) && !type.IsAbstract).AsImplementedInterfaces().InstancePerLifetimeScope(); //MVC控制器注入 builder.RegisterControllers(Assembly.GetExecutingAssembly()); //MVC过滤器注入 builder.RegisterFilterProvider(); var container = builder.Build(); DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); }
错误:
None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'Tribe.PC.Web.Controllers.AccountController' can be invoked with the available services and parameters:
Cannot resolve parameter 'Tribe.PC.IService.Account.IUser userService' of constructor 'Void .ctor(Tribe.PC.IService.Account.IUser)'.
如果不继承BaseController,则代码运行正常,求解!
@dudu
你不把你怎么注册和BaseController贴出来dudu都帮不了你
//MVC控制器注入
builder.RegisterControllers(Assembly.GetExecutingAssembly());
注册不是这句话就搞定了吗?
@笑看山河: 我怀疑 builder.RegisterControllers(Assembly.GetExecutingAssembly()) 的实现中会考察 AccountController 的父类是否为 Controller,因此间接继承就会失败,你可以看下它的源码。
@Launcher: 我看看!谢谢
官方文档,里面貌似有解释,好像实现自定义Controller比较复杂,英文不好,看是否一个意思?
http://docs.autofac.org/en/latest/advanced/multitenant.html?highlight=controller#tenant-specific-controllers
@笑看山河: 就是这个意思。你看它给的例子,如果在同一个程序集,你需要显示注册,类似:// If you have tenant-specific controllers in the same assembly as the
// application, you should register controllers individually.
builder.RegisterType<HomeController>();
// Create the multitenant container and the tenant overrides.
var mtc = new MultitenantContainer(tenantIdStrategy, builder.Build());
mtc.ConfigureTenant("1",
b =>
{
b.RegisterType<Tenant1Dependency>().As<IDependency>().InstancePerDependency();
b.RegisterType<Tenant1Controller>().As<HomeController>();
});
如果不在同一个程序集,直接使用 builder.RegisterControllers(Assembly.GetExecutingAssembly()) 就可以了,但是要注意是否引用了程序集或程序集是否被加载进引用。
@Launcher: 试了下,挺费劲,没搞定,呵呵!