[英]Autofac resolving dependencies
I am really new to autofac and having issues. 我对autofac真的很陌生,并且遇到了问题。 I am using Web API and I have set my module up like this:
我正在使用Web API,并且已将模块设置如下:
public class CormarModule : Module
{
// Fields
private readonly string _connectionStringName;
private readonly connectionType _connection;
/// <summary>
/// Default constructor
/// </summary>
public CormarModule() {
_connectionStringName = ConfigurationManager.AppSettings["ConnectionStringName"];
_connection = _connectionStringName.ToUpper().Contains("LIVE") ? connectionType.Live : connectionType.Test;
}
protected override void Load(ContainerBuilder builder)
{
// Singletons
builder.RegisterType<DatabaseContext>().As<DatabaseContext>().SingleInstance();
builder.RegisterType<UnitOfWork<DatabaseContext>>().As<IUnitOfWork>().SingleInstance();
builder.Register(c => new OracleUnitOfWork(_connectionStringName)).As<IOracleUnitOfWork>().SingleInstance();
builder.Register(c => new AdvancedEncryptionStandardProvider(ConfigurationManager.AppSettings["rm:key"], ConfigurationManager.AppSettings["rm:secret"])).As<IAdvancedEncryptionStandardProvider>().SingleInstance();
// Register our services
builder.RegisterType<AccountService>().As<IAccountService>();
builder.RegisterType<DeliveryInformationService>().As<IDeliveryInformationService>();
builder.RegisterType<EmailService>().As<IEmailService>();
builder.RegisterType<LogService>().As<ILogService>();
builder.RegisterType<OrderService>().As<IOrderService>();
builder.RegisterType<OrderLineService>().As<IOrderLineService>();
builder.RegisterType<PaymentHistoryService>().As<IPaymentHistoryService>();
builder.RegisterType<PrincipleProvider>().As<IPrincipleProvider>();
builder.RegisterType<ProductService>().As<IProductService>();
builder.RegisterType<RefreshTokenService>().As<IRefreshTokenService>();
builder.RegisterType<StockService>().As<IStockService>();
builder.Register(c => new UserStore<User>(c.Resolve<DatabaseContext>())).As<IUserStore<User>>();
// Single instance
builder.RegisterType<OAuthProvider>().As<OAuthProvider>();
builder.RegisterType<LogProvider>().As<ILogProvider>();
builder.RegisterType<RefreshTokenProvider>().As<IAuthenticationTokenProvider>();
builder.Register(c => new SendGridProvider(c.Resolve<IUnitOfWork>(), c.Resolve<IEmailService>(), ConfigurationManager.AppSettings["SendGridApiKey"])).As<ISendGridProvider>();
builder.Register(c => new UserProvider(_connectionStringName, c.Resolve<IUserStore<User>>(), c.Resolve<IAdvancedEncryptionStandardProvider>(), c.Resolve<ISendGridProvider>())).As<IUserProvider>();
// Per request
builder.RegisterType<DeliveryInformationProvider>().As<IDeliveryInformationProvider>().InstancePerRequest();
builder.RegisterType<JournalProvider>().As<IJournalProvider>().InstancePerRequest();
builder.RegisterType<StockProvider>().As<IStockProvider>().PropertiesAutowired(PropertyWiringOptions.AllowCircularDependencies).InstancePerRequest();
builder.Register(c => new AccountProvider(_connection, c.Resolve<IAccountService>(), c.Resolve<IPrincipleProvider>(), c.Resolve<IAdvancedEncryptionStandardProvider>(), c.Resolve<IPaymentHistoryService>())).As<IAccountProvider>().InstancePerRequest();
builder.Register(c => new ProductProvider(_connection, c.Resolve<IProductService>())).As<IProductProvider>().InstancePerRequest();
builder.Register(c => new OrderProvider(_connection, c.Resolve<IOrderService>(), c.Resolve<IPrincipleProvider>(), c.Resolve<IAdvancedEncryptionStandardProvider>())).As<IOrderProvider>().PropertiesAutowired(PropertyWiringOptions.AllowCircularDependencies).InstancePerRequest();
builder.Register(c => new OrderLineProvider(_connection, c.Resolve<IOrderLineService>(), c.Resolve<IPrincipleProvider>(), c.Resolve<IAdvancedEncryptionStandardProvider>())).As<IOrderLineProvider>().InstancePerRequest();
}
}
I am struggling with the different scopes. 我正在努力应对不同的范围。 A little background before I explain my issue.
在我解释我的问题之前需要一些背景知识。
Each Provider has a required Service and each Controller has one or more Providers injected. 每个提供程序都有所需的服务 ,每个控制器都有一个或多个注入的提供程序 。 Each Provider could have an optional Provider which should only be resolved when a method invokes that provider.
每个提供程序都可以有一个可选的提供程序 ,仅当方法调用该提供程序时才应解析该提供程序。
The problem I have is I don't know how to set that up. 我的问题是我不知道该如何设置。 I was going to inject the lifetime scope into the constructor and in the method, resolve the required Provider , but I have read this is bad practice, plus it would create a new instance.
我打算将生存期范围注入到构造函数中,并在方法中解析所需的Provider ,但是我已经读到这是一种不好的做法,而且还会创建一个新实例。 I would like to use one instance per request, but only if it is need in that request.
我想为每个请求使用一个实例,但前提是该请求中需要它。
I hope that makes sense and I hope someone can help! 我希望这是有道理的,希望有人能提供帮助!
IMO, you're doing pretty good. 海事组织,你做得很好。
What you need is to take a dependency on a Func<Provider>
. 您需要依赖于
Func<Provider>
。 When you ask Autofac a Func<>
it returns a factory method, to be called instead of .Resolve<Provider>
. 当您要求Autofac
Func<>
它将返回一个工厂方法,而不是.Resolve<Provider>
来调用。
See here and here for documentation. 请参阅此处和此处的文档。
You can write it this way: 您可以这样写:
private OptionalProvider _instance;
private Func<OptionalProvider> _providerGetter;
public OptionalProvider Prov
{
get { return _instance ?? (_instance = _providerGetter()); }
}
public MyProvider(Func<OptionalProvider> getter)
{
_providerGetter = getter;
}
public void MethodRequiringOptionalProvider()
{
// just use property Prov and let Autofac handle the rest
}
Another suggestion: instead of injecting directly the _connection string parameter, just create a CormarConfig
class, to be registered with .RegisterInstance
to store all your configuration options. 另一个建议:与其直接注入_connection字符串参数,
CormarConfig
创建一个CormarConfig
类,该类.RegisterInstance
注册以存储所有配置选项。 This way you just call RegisterType
and let Autofac resolve all the type parameters (you get rid of those ugly Resolve
calls). 这样,您只需调用
RegisterType
并让Autofac解析所有类型参数(即可摆脱那些难看的Resolve
调用)。
If all your services inherit from a common ancestor or implement a common interface, you can register them all via Assembly Scanning and AsImplementedInterfaces
. 如果您的所有服务都继承自一个共同的祖先或实现一个共同的接口,则可以通过Assembly Scanning和
AsImplementedInterfaces
全部注册。 You would get rid of all the clutter in your module. 您将摆脱模块中的所有混乱情况。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.