簡體   English   中英

使用StructureMap配置具體類的屬性

[英]Configure a Property of a Concrete Class using StructureMap

我在Application實例中使用了一組通用的電子郵件類。 它們都共享相同的接口,但是我需要(可選)“填充”另一個“公共”類型的實例作為屬性。

從這里開始:鑒於這個起點...
注意,MyApplication從所有3個屬性開始。 而且,由於DistributionListProvider是唯一配置的IInstanceProvider,因此不會出現任何問題。

public class MyApplication : IMyApplication
{       
    #region notifications

    [SetterProperty]
    public IEmailNotification RequestToFlowEmailNotification { get; set; }

    [SetterProperty]
    public IEmailNotification ApprovalToFlowEmailNotification{ get; set; }

    #endregion

    #region instance providers

    [SetterProperty]
    public IInstanceProvider DistributionListProvider { get; set; }

    #endregion
}

public class RequestToFlowEmailNotification : IEmailNotification
{
    #region <Properties>

    [SetterProperty]
    public IInstanceProvider DistributionListProvider { get; set; }

    #endregion
}

public class ApprovalToFlowEmailNotification : IEmailNotification
{

}

public class DistributionListProvider : ComponentProviderBase, IInstanceProvider
{

}

新增:現在讓我們創建另一個IInstanceProvider並將其添加到APPLICATION ...
但首先,請注意IEmailNotification和IInstanceProvider是常見類型,而不是“通用類型” ...意味着它們不是EmailNotificationFor<T>類型。 這使您在注冊表中配置它們的方式有所不同。

// NOW...LETS ADD THIS !!
public class AuthorizationToFlowMeterDocumentRecallProvider : ComponentProviderBase, IInstanceProvider
{

}

public class MyApplication : IMyApplication
{       
    #region notifications

    [SetterProperty]
    public IEmailNotification RequestToFlowEmailNotification { get; set; }

    [SetterProperty]
    public IEmailNotification ApprovalToFlowEmailNotification{ get; set; }

    #endregion

    #region instance providers

    [SetterProperty]
    public IInstanceProvider DistributionListProvider { get; set; }

    [SetterProperty]
    public IInstanceProvider AuthorizationToFlowMeterDocumentRecallProvider{ get; set; }

    #endregion
}

此時StructureMap不再需要了解如何填寫...

  • RequestToFlowEmailNotification.DistributionListProvider

問:如何更新注冊表以強制正確填充StructureMap?
以下是我的整個注冊表...

注意:
我不想設置默認值...是否可以在不設置默認值的情況下執行此操作?

public ContainerRegistry()
{
    Scan(
        scan =>
        {
            scan.TheCallingAssembly();
            scan.WithDefaultConventions();
            scan.LookForRegistries();
            scan.SingleImplementationsOfInterface();
        });

    // ------------
    // UNIT OF WORK
    // ------------
    // DbContext
    For<DbContext>().Use<MeasurementContractsDbContext>();

    // UnitOfWork
    For<IMeasurementContractsUnitOfWork>().Use<MeasurementContractsUnitOfWork>();

    // GenericRepository
    For(typeof(ICompositeRepository<>)).Use(typeof(GenericRepository<>));

    // --------
    // HELPERS
    // --------
    For<IWindowsIdentityHelper>().Use<WindowsIdentityHelper>();

    For<ISmtpClientHelper>().Use<SmtpClientHelper>()
        .Ctor<ISmtpClient>().Is(new SmtpClient());

    For<IPdfConverterHelper>().Use<PdfConverterHelper>()
        .Ctor<IPdfConverterClient>().Is(new SelectPdfUrlConverterClient());

    // WARNING: Do not remove without replacing it with "some kind of" IConstructorSelector, so that, Unit Testing can be done
    For<IDataServiceFor<EmployeeData>>()
        .Use(x => new EmployeeDataService(new ODataProxyV4())); //<-- uses this constructor

    // --------
    // WORKFLOW
    // ---------
    For<IWorkflowProvider>().Use<WorkflowProvider>()
        .Ctor<Assembly>().Is(Assembly.GetExecutingAssembly());

    // --------
    // MANAGERS
    // --------
    For<IManager<Device>>().Use<DeviceManager>();
    For<IManager<Favorite>>().Use<FavoritesManager>();
    For<IManager<User>>().Use<UserManager>();

    // --------
    // DEPENDENCY MANAGERS
    // --------
    For<IDocumentDependency>().Use<DeviceAffinityProvider>();

    // --------
    // TRANSFORMERS
    // --------
    For<IXmlTransformerFor<AuthorizationToFlowMeterDocumentXmlDataSet>>().Use<AuthorizationToFlowMeterDocumentXmlTransformer>();
    For<IXmlTransformerFor<FirstDeliveryNoticeDocumentXmlDataSet>>().Use<FirstDeliveryNoticeDocumentXmlTransformer>();
    For<IXmlTransformerFor<RequestToFlowMeterDocumentXmlDataSet>>().Use<RequestToFlowMeterDocumentXmlTransformer>();

    // --------
    // PROVIDERS: DataItem Providers
    // --------
    For<IDataItemProviderFor<EmployeeData>>().Use<EmployeeDataProvider>();

    // --------
    // PROVIDERS: Document Providers
    // --------
    For<IDataItemProviderFor<RequestToFlowMeterDocument>>().Use<RequestToFlowMeterDocumentProvider>();
    For<IDataItemProviderFor<AuthorizationToFlowMeterDocument>>().Use<AuthorizationToFlowMeterDocumentProvider>();
    For<IDataItemProviderFor<FirstDeliveryNoticeDocument>>().Use<FirstDeliveryNoticeDocumentProvider>();

    // --------
    // COMMANDS
    // --------
    For<IAdminUpdateCommandFor<AuthorizationToFlowMeterDocument>>().Use<AuthorizationToFlowMeterDocumentAdminUpdateCommand>();

    // -----------
    // APPLICATION
    // -----------
    For<IMyApplication>().Use<MyApplication>()

        // Instance Provider
        .Setter(x => x.DistributionListProvider).Is<DistributionListProvider>()
        .Setter(x => x.AuthorizationToFlowMeterDocumentRecallProvider).Is<AuthorizationToFlowMeterDocumentRecallProvider>()

        // Email Notifications
        .Setter(x => x.ApprovalToFlowEmailNotification).Is<ApprovalToFlowEmailNotification>()
        .Setter(x => x.DenialToFlowEmailNotification).Is<DenialToFlowEmailNotification>()
        .Setter(x => x.ApprovalToFlowRecalledEmailNotification).Is<ApprovalToFlowRecalledEmailNotification>()
        .Setter(x => x.RequestToFlowEmailNotification).Is<RequestToFlowEmailNotification>()
        .Setter(x => x.FirstDeliveryNoticeEmailNotification).Is<FirstDeliveryNoticeEmailNotification>();
}

使用[SetterProperty]屬性,StructureMap將嘗試構建該屬性並將其值附加為對象構造的一部分。

但是,setter屬性需要默認實現,因為當存在多個實現時,或者尤其是未添加默認實現時,它無法確定要使用哪個實現。

使用RequestToFlowEmailNotification.DistributionListProvider ,容器不知道要使用哪個實現。

若要覆蓋此行為,請對RequestToFlowEmailNotification.DistributionListProvider使用內聯設置器配置

//...
.Setter(x => x.RequestToFlowEmailNotification)
    .Is<RequestToFlowEmailNotification>(_ => 
        _.Setter(d => d.DistributionListProvider)
            .Is<DistributionListProvider>()); //<<-- change to which ever one is needed

請注意Setter配置的鏈接以便設置RequestToFlowEmailNotification ,然后設置內部DistributionListProvider

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM