首页 > 解决方案 > Service Fabric Autofac如何?

问题描述

我正在尝试在我的 SF 中的有状态服务中配置 IoC(我还不太熟悉的概念),如下所述:https ://www.codeproject.com/Articles/1217885/Azure-Service-Fabric-demo在这里:https ://alexmg.com/posts/introducing-the-autofac-integration-for-service-fabric 。

在 program.cs - 主要:

var builder = new ContainerBuilder();
builder.RegisterModule(new GlobalAutofacModule());
builder.RegisterServiceFabricSupport();
builder.RegisterStatefulService<Payment>("PaymentType");

using (builder.Build())
{
    ServiceEventSource.Current.ServiceTypeRegistered(Process.GetCurrentProcess().Id, typeof(Payment).Name);
    Thread.Sleep(Timeout.Infinite);
}

GlobalAutofac 模块:

public class GlobalAutofacModule : Module
{
    protected override void Load(ContainerBuilder builder)
    {
        builder.RegisterType<ChargeRepository>().As<IChargeRepository>().SingleInstance();
        builder.RegisterType<CustomerRepository>().As<ICustomerRepository>().SingleInstance();
        builder.RegisterType<InvoiceItemRepository>().As<IInvoiceItemRepository>().SingleInstance();
        builder.RegisterType<PlanRepository>().As<IPlanRepository>().SingleInstance();
        builder.RegisterType<ProductRepository>().As<IProductRepository>().SingleInstance();
        builder.RegisterType<SourceRepository>().As<ISourceRepository>().SingleInstance();
        builder.RegisterType<SubscriptionRepository>().As<ISubscriptionRepository>().SingleInstance();
        builder.RegisterType<TokenRepository>().As<ITokenRepository>().SingleInstance();
    }
}

调用服务没有问题

        public Payment(StatefulServiceContext context, 
        IChargeRepository chargeRepo, 
        ICustomerRepository customerRepo,
        IInvoiceItemRepository invoiceItemRepo,
        IPlanRepository planRepository,
        IProductRepository productRepo,
        ISourceRepository sourceRepo,
        ISubscriptionRepository subscriptionRepo,
        ITokenRepository tokenRepo)
        : base(context)
    { ... }

在其中一种方法中,它需要调用自定义映射器(缺少参数时出错)

var test = new Mapper().GetProductsDto(false, false);

该类的定义如下:

    private readonly IChargeRepository _chargeRepo;
    private readonly ICustomerRepository _customerRepo;
    private readonly IInvoiceItemRepository _invoiceItemRepo;
    private readonly IPlanRepository _planRepo;
    private readonly IProductRepository _productRepo;
    private readonly ISourceRepository _sourceRepo;
    private readonly ISubscriptionRepository _subscriptionRepo;
    private readonly ITokenRepository _tokenRepo;

    public Mapper(IChargeRepository chargeRepo,
        ICustomerRepository customerRepo,
        IInvoiceItemRepository invoiceItemRepo,
        IPlanRepository planRepository,
        IProductRepository productRepo,
        ISourceRepository sourceRepo,
        ISubscriptionRepository subscriptionRepo,
        ITokenRepository tokenRepo)
    {
        _chargeRepo = chargeRepo;
        _customerRepo = customerRepo;
        _invoiceItemRepo = invoiceItemRepo;
        _planRepo = planRepository;
        _productRepo = productRepo;
        _sourceRepo = sourceRepo;
        _subscriptionRepo = subscriptionRepo;
        _tokenRepo = tokenRepo;
    }
public IEnumerable<ProductListDto> GetStripeProductsDto(bool isLogged, bool isSubscriber) {...}

那么如何实例化映射器并调用该方法而不将每个 repo 都作为参数传递呢?

编辑: tmp 解决方案,直到批准/不批准

    private static void Main()
    {
        try
        {
            using (ContainerOperations.Container)
            {
                ServiceEventSource.Current.ServiceTypeRegistered(Process.GetCurrentProcess().Id, typeof(Payment).Name);
                Thread.Sleep(Timeout.Infinite);
            }
        }
        catch (Exception e)
        {
            ServiceEventSource.Current.ServiceHostInitializationFailed(e.ToString());
            throw;
        }
    }
}

public class ContainerOperations
{
    private static readonly Lazy<IContainer> _containerSingleton =
        new Lazy<IContainer>(CreateContainer);

    public static IContainer Container => _containerSingleton.Value;

    private static IContainer CreateContainer()
    {
        var builder = new ContainerBuilder();
        builder.RegisterModule(new GlobalAutofacModule());
        builder.RegisterServiceFabricSupport();
        builder.RegisterStatefulService<Payment>("Inovatic.SF.Windows.PaymentType");
        return builder.Build();
    }
}


public class GlobalAutofacModule : Module
{
    protected override void Load(ContainerBuilder builder)
    {
        //builder.RegisterType<Mapper>();

        builder.RegisterType<ChargeRepository>().As<IChargeRepository>().SingleInstance();
        builder.RegisterType<CustomerRepository>().As<ICustomerRepository>().SingleInstance();
        builder.RegisterType<InvoiceItemRepository>().As<IInvoiceItemRepository>().SingleInstance();
        builder.RegisterType<PlanRepository>().As<IPlanRepository>().SingleInstance();
        builder.RegisterType<ProductRepository>().As<IProductRepository>().SingleInstance();
        builder.RegisterType<SourceRepository>().As<ISourceRepository>().SingleInstance();
        builder.RegisterType<SubscriptionRepository>().As<ISubscriptionRepository>().SingleInstance();
        builder.RegisterType<TokenRepository>().As<ITokenRepository>().SingleInstance();

    }
}

调用现在是这样的: var productListDto = Mapper.GetStripeProductsDto(isLogged, false); 映射器:

    private static IProductRepository _productRepo => ContainerOperations.Container.Resolve<IProductRepository>();

    public static IEnumerable<ProductListDto> GetStripeProductsDto(bool isLogged, bool isSubscriber)
    {
        var productList = _productRepo.GetAllStripeProducts().ToList();

标签: autofacazure-service-fabric

解决方案


我认为您还应该在 IoC 容器中注册 Mapper 类并将其添加到 Payment 的构造函数中,然后容器将为您创建包含所有必需参数的 Mapper。你可以调用类似的东西来做到这一点 builder.RegisterType<Mapper>().SingleInstance();


推荐阅读