RT, 目前场景是 一个core 2.1 的web程序,使用autofac进行了service的注入(接口),并且在controller 中使用构造函数注入或者属性注入都可以正常work。
此时写了个 baseWebController ,该基类内部需要用到一个 IServiceA 的一个funA()去获取一个 user对象,并保存在基类里,因为有很多controller 都会用到当前这个user对象, 那么问题来了,baseWebController 里边尝试使用属性注入 IServiceA 始终得不到注入的对象,如果改成构造函数注入,那么所有的controller 都要 额外写 构造函数(IServiceA a): base(a)
感觉这样的改动面是不是有点大了? 有什么合适的解决方案吗?
public interface IEngine {
T Resolve<T>() where T : class; object Resolve(Type type); IEnumerable<T> ResolveAll<T>(); object ResolveUnregistered(Type type); }
public class EngineContext { public static IEngine Create() => Singleton<IEngine>.Instance ?? (Singleton<IEngine>.Instance = new Engine()); public static void Replace(IEngine engine) => Singleton<IEngine>.Instance = engine; public static IEngine Current { get { if (Singleton<IEngine>.Instance == null) { Create(); } return Singleton<IEngine>.Instance; } } }
public class Engine : IEngine { private IServiceProvider _serviceProvider { get; set; } public virtual IServiceProvider ServiceProvider => _serviceProvider; protected IServiceProvider GetServiceProvider() { var accessor = ServiceProvider.GetService<IHttpContextAccessor>(); var context = accessor.HttpContext; return context != null ? context.RequestServices : ServiceProvider; } public T Resolve<T>() where T : class { return (T)GetServiceProvider().GetRequiredService(typeof(T)); } public object Resolve(Type type) { return GetServiceProvider().GetRequiredService(type); } public IEnumerable<T> ResolveAll<T>() { return (IEnumerable<T>)GetServiceProvider().GetService(typeof(T)); } public object ResolveUnregistered(Type type) { Exception innerException = null; foreach (var constructor in type.GetConstructors()) { try { var parameters = constructor.GetParameters().Select(parameter => { var service = Resolve(parameter.ParameterType); if (service == null) throw new Exception("Unknown dependency"); return service; }); return Activator.CreateInstance(type, parameters.ToArray()); } catch (Exception ex) { innerException = ex; } } throw new ArgumentException("No constructor was found that had all the dependencies satisfied.", innerException); } }
public class Singleton<T> : Singleton { private static T _instance; public static T Instance { get => _instance; set { _instance = value; AllSingletons[typeof(T)] = value; } } } public class SingletonList<T> : Singleton<IList<T>> { static SingletonList() { Singleton<IList<T>>.Instance = new List<T>(); } public new static IList<T> Instance => Singleton<IList<T>>.Instance; } public class SingletonDictionary<TKey, TValue> : Singleton<IDictionary<TKey, TValue>> { static SingletonDictionary() { Singleton<Dictionary<TKey, TValue>>.Instance = new Dictionary<TKey, TValue>(); } public new static IDictionary<TKey, TValue> Instance => Singleton<Dictionary<TKey, TValue>>.Instance; } public class Singleton { static Singleton() { AllSingletons = new ConcurrentDictionary<Type, object>(); } public static IDictionary<Type, object> AllSingletons { get; } }
在BaseController调用方法
var serviceA = EngineContext.Current.Resolve<IServiceA>();
这个方法提取自nopCommerce,可以在github找到
多谢,我大概看了一下,我这边目前的实现比较简单粗暴,直接把 IServiceProvider 在startup 那里边 给赋值存到了一个公共静态资源类 里边,然后通过 ServiceProvider.GetRequiredService<接口名>(); 这样来做,大概意思应该是 直接取通道里边的 实例,但也只是个别地方使用, 所以就先这么过去了
这得看你的注入代码是咋写的了。
对于 Controller ,如果使用 asp.net core 自带的依赖注入,通过 [FromServices] IServiceA serviceA
这样的方法参数声明就可以
请问下最佳答案中的代码,我在var accessor = ServiceProvider.GetService<IHttpContextAccessor>();这一步报错了啊
请问你的问题解决了么,我现在也是碰到这样的问题,子类都属性注册没问题,然后基类属性注册出来的为null。场景和你的一样,如果你解决了,能听下解决的那几步代码么。
你解决了吗?我也遇见了 我用的.net core 3.1