我的问题是在Autofac(SimpleInjector正常工作)中如何创建可以从MVC控制器和类库轻松访问的静态类,有很多类似的问题,但我仍然没有得到答案我正在寻求
我正在尝试使用MVC背后的类库中的Autofac解析器并获得错误"没有标记匹配的范围' AutofacWebRequest'从请求实例的范围中可见。 "
好的,这是故事的开始。我有单独的类EngineContext,它包含我的diContainer,在我的类库中我试图使用EngineContext.DiContainer.GetInstance()它会得到这个错误,因为我从singlton实例类调用了resolver。
我做了我的研究,以不同的方式工作,但没有运气。当我使用DepedencyResolver.Current.GetService它说HttpContext错误然后我试图从global.asax传递DependencyResolver.Current但它在解析我的请求类型时总是返回null。
也试过了 。builder.RegisterType()InstancePerMatchingLifetimeScope("子&#34) 使用(var lifetime = container.BeginLifetimeScope(" child")){ 但同样的说,没有范围与标签"孩子"范围等等。
目前这项工作在我的Controller构造函数和静态类调用中。但是如果我从内层控制器方法或下层的类库中调用解析器,它就无法工作。以下是我的代码
MVC启动
[assembly: PreApplicationStartMethod(typeof(ModuleConfig), "Start")]
[assembly: ApplicationShutdownMethod(typeof(ModuleConfig), "Stop")]
namespace NexusCore.Admin
{
public class ModuleConfig
{
public static void Start()
{
EngineConfig();
}
public static void Stop()
{
}
private static void EngineConfig()
{
// Dependancy Injection initialize
EngineContext.Instance.Initialize(new AutofacFactory(
builder =>
{
builder.RegisterControllers(typeof (MvcApplication).Assembly);
// Unit of Work
builder.RegisterType<ContentContext>().As<IContentContext>().InstancePerLifetimeScope();
builder.RegisterType<UnitOfWork>().As<IUnitOfWork>().InstancePerRequest();
builder.RegisterType<WebErrorHandlerFactory>().As<IErrorHandlerFactory>().InstancePerLifetimeScope();
},
new AutofacRegisterAdmin(),
container => DependencyResolver.SetResolver(new AutofacDependencyResolver(container))));
}
}
}
EngineContext
public class EngineContext : IEngine
{
private static IEngine _instance;
public static IEngine Instance
{
get { return _instance ?? (_instance = new EngineContext()); }
}
private IDiContainer _diContainer;
private ICurrentUserProvider _currentUserProvider;
public IDiContainer DiContainer
{
get
{
if (_diContainer == null)
{
var error = ErrorAdapter.ModelState.AddModelError("", "",
logCode: LogCode.CriticalEngineDiContainerNotInitialized);
throw new Exception(error.ErrorMessage);
}
return _diContainer;
}
}
public ICurrentUserProvider CurrentUser
{
get
{
if (_currentUserProvider == null)
{
var error = ErrorAdapter.ModelState.AddModelError("", "",
logCode: LogCode.CriticalEngineCurrentUserProviderNotInitialized);
throw new Exception(error.ErrorMessage);
}
return _currentUserProvider;
}
}
public void Initialize(IDiContainerFactory diContainerFactory)
{
DiContainerInitialize(diContainerFactory);
CurrentUserProviderInitialize();
}
private void DiContainerInitialize(IDiContainerFactory diContainerFactory)
{
_diContainer = diContainerFactory.Create();
}
private void CurrentUserProviderInitialize()
{
_currentUserProvider = _diContainer.GetInstance<ICurrentUserProvider>();
}
}
迪工厂
public class AutofacFactory : IDiContainerFactory
{
private readonly IContainer _container;
public AutofacFactory(Action<ContainerBuilder> preRegister, IDiRegister register, Action<IContainer> resolver)
{
var builder = new ContainerBuilder();
preRegister(builder);
// init register
Register(builder, register);
_container = builder.Build();
resolver(_container);
}
private void Register(ContainerBuilder builder, IDiRegister register)
{
register.SetBuilder(builder);
register.Register();
}
public IDiContainer Create()
{
return new AutofacContainer(_container);
}
}
Di Container
public class AutofacContainer : IDiContainer
{
private readonly IContainer _container;
public AutofacContainer(IContainer container)
{
_container = container;
}
public TService GetInstance<TService>() where TService : class
{
using (var scope = _container.BeginLifetimeScope())
{
return scope.Resolve<TService>(); // change this line many times.
}
}
}
哪里不行?
public class ComponentServices : IComponentServices
{
public IInstallationService InstallationService
{
get { return GetInstance<IInstallationService>(); }
}
public IMembershipService MembershipService
{
get { return GetInstance<IMembershipService>(); }
}
private T GetInstance<T>() where T : class
{
return EngineContext.Instance.DiContainer.GetInstance<T>(); // Not work in class library
}
}
在Controller中,如果我直接使用membshipService,它就可以正常工作
[Authorize]
public class AccountController : Controller
{
private readonly Infrasructure.Security.IAuthenticationManager _userManager;
//private readonly IComponentServices _services;
private readonly IMembershipService _memberhsip;
public AccountController(Infrasructure.Security.IAuthenticationManager userManager, IMembershipService membership)
{}
在Controller中,如果我使用ComponenetServices然后使用_services.MembershipServices,它将收到错误。因为ComponentServices尝试调用EngineContext.DiContainer.GetInstanct(),然后使用Tag匹配&#34; AutofacWebRequest&#34;错误会回来。
答案 0 :(得分:0)
最后,我发现ComponentService的目的可以通过使用属性注入来简单解决,我已经过度复杂了。
public class ComponentServices : IComponentServices
{
public IInstallationService InstallationService { get; set; }
public IMembershipService MembershipService { get; set; }
}
只有1行需要修改,然后依赖性解析器会自动注入它们。
Builder.RegisterType<ComponentServices>().As<IComponentServices>().InstancePerLifetimeScope().PropertiesAutowired();
我的不好,太混淆了。