第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

在 Autofac 中使用多態(tài)性時解析具體類型

在 Autofac 中使用多態(tài)性時解析具體類型

C#
函數(shù)式編程 2022-01-15 19:40:03
考慮以下代碼:public interface IFileBackup{    Task Backup(byte[] file);}public class BackUpMechanismA : IFileBackup{    //Implementation    public async Task Backup(byte[] file)    {        //Attempts to backup using mechanism A    }}public class BackUpMechanismB : IFileBackup{    //Implementation    public async Task Backup(byte[] file)    {        //Attempts to backup using mechanism B    }}然后調(diào)用類如下所示:public class Caller{    private readonly IFileBackup _backupA;    private readonly IFileBackup _backupB;    public Caller(IFileBackup backupA, IFileBackup backupB)    {        _backupA = backupA;        _backupB = backupB;    }     public async Task BackupFile(byte[] file)     {         try         {             await _backupA.Backup(file);         }         catch(SomeException)         {             await _backupB.Backup(file);         }     }}所以我在這里嘗試做的是使用多態(tài)性。所以兩者都BackupMechanismA以自己的方式BackupMechanismB實現(xiàn)該方法。Backup在調(diào)用者中,我想嘗試第一種機制,如果這不起作用,我們捕獲異常并嘗試第二種方法。我無法使用Autofac. 我嘗試過:builder.RegisterType<BackupMechanismA>().As<IFileBackup>().AsSelf(); builder.RegisterType<BackupMechanismB>().As<IFileBackUp>().AsSelf();但這不起作用,因為我仍然需要告訴調(diào)用者要解析哪種類型。我如何在來電者中做到這一點?另外,我懷疑這種設(shè)計是否真的是正確的設(shè)計。在此設(shè)計之前,我只有一個具有兩種不同方法的類,一種用于機制 A,一種用于機制 B,然后調(diào)用者將在 try catch 中調(diào)用不同的方法。所以我想重構(gòu)它,因為這個類變得非常大,我想把這兩種不同的機制分離到它們自己的類中。那么,我可以使用 Autofac 解決這個問題嗎?對于這種情況,它是正確的設(shè)計嗎?
查看完整描述

3 回答

?
絕地?zé)o雙

TA貢獻1946條經(jīng)驗 獲得超4個贊

同意 Jogge 的觀點,迭代IFileBackups 會是一個更好的選擇,但是為每種類型創(chuàng)建一個接口是不行的。相反,您可以添加一個提供IEnumerable<IFileBackup>(聚合)的類。例如:


public class BackupBundle : IEnumerable<IFileBackup>

{

    private readonly List<IFileBackup> _backups = new List<IFileBackup>();


    // default constructor creates default implementations

    public BackupBundle()

        : this(new List<IFileBackup> {new BackUpMechanismA(), new BackUpMechanismB()}) {}


    // allow users to add custom backups

    public BackupBundle(IEnumerable<IFileBackup> backups)

    {

        foreach (var backup in backups)

            Add(backup);

    }


    public void Add(IFileBackup backup)

    {

        if (backup == null) throw new ArgumentNullException(nameof(backup));

        _backups.Add(backup);

    }


    public IEnumerator<IFileBackup> GetEnumerator()

    {

        foreach (var backup in _backups)

            yield return backup;

    }


    IEnumerator IEnumerable.GetEnumerator()

    {

        return GetEnumerator();

    }

}


public class Caller

{

    private readonly IEnumerable<IFileBackup> _backups;


    public Caller(IEnumerable<IFileBackup> backups)

    {

        _backups = backups ?? throw new ArgumentNullException(nameof(backups));

    }


    public async Task BackupFile(byte[] file)

    {

        foreach (var b in _backups)

        {

            try

            {

                await b.Backup(file);

                break;

            }

            catch (Exception e) { }

        }

    }

}

注冊可按以下方式進行:


builder.RegisterInstance(new BackupBundle()).As<IEnumerable<IFileBackup>>();

builder.RegisterType<Caller>();

它允許您按類名解析:


var caller = scope.Resolve<Caller>();

如您所見,BackupBundle具有BackUpMechanismA和的依賴關(guān)系BackUpMechanismB。您可以通過引入另一層抽象來擺脫它,但我不想這樣做。我主要關(guān)心的是使Caller更健壯。您可能想要引入重試邏輯、超時等。


查看完整回答
反對 回復(fù) 2022-01-15
?
慕桂英3389331

TA貢獻2036條經(jīng)驗 獲得超8個贊

為了使您的設(shè)計工作,您可以嘗試下一種方法:


static void Main(string[] args)

{

    var builder = new ContainerBuilder();

    builder.RegisterType<BackUpMechanismA>().Keyed<IFileBackup>("A");

    builder.RegisterType<BackUpMechanismB>().Keyed<IFileBackup>("B");

    builder.RegisterType<Caller>()

            .WithParameter((p, ctx) => p.Position == 0, (p, ctx) => ctx.ResolveKeyed<IFileBackup>("A"))

            .WithParameter((p, ctx) => p.Position == 1, (p, ctx) => ctx.ResolveKeyed<IFileBackup>("B"));

    IContainer container = builder.Build();


    var caller = container.Resolve<Caller>();


    Console.ReadKey();

}

但是在我看來,您可能在這里不需要這樣的多態(tài)性。實現(xiàn)這樣的東西會更加明顯和描述性:


public async Task BackupFile(byte[] file)

{

    try

    {

        await BackUpToAmazonS3(file);

    }

    catch (AmazonS3LoadingException)

    {

        await BackUpToLocalDisk(file);

    }

}

在這個例子中,很明顯發(fā)生了什么。在那里BackUpToAmazonS3你可以使用一些注入AmazonS3FileBackUp和BackUpToLocalDisk使用中的LocalDiskFileBackUp東西。關(guān)鍵是當(dāng)您不打算更改實現(xiàn)時,您不需要多態(tài)性。在您的上下文中應(yīng)該清楚嗎?您嘗試將備份放入某個遠程存儲,然后,如果失敗,則放入本地磁盤。您無需在此處隱藏含義。這是你的邏輯,應(yīng)該很清楚,當(dāng)你閱讀代碼時,我想。希望能幫助到你。


查看完整回答
反對 回復(fù) 2022-01-15
?
紅糖糍粑

TA貢獻1815條經(jīng)驗 獲得超6個贊

嘗試使用名稱注冊,然后使用名稱解析:


builder.RegisterType<BackupMechanismA>().Named<IFileBackup>("BackUpMechanismA");

builder.RegisterType<BackupMechanismB>().Named<IFileBackUp>("BackUpMechanismB");


_backupA = container.ResolveNamed<IFileBackUp> 

("BackUpMechanismA"); 

_backupB = container.ResolveNamed<IFileBackUp> 

("BackUpMechanismB");

在運行時解析實例,而不是通過構(gòu)造函數(shù)注入。這將讓您根據(jù)需要解析為相應(yīng)的類型。讓我知道這個是否奏效。


查看完整回答
反對 回復(fù) 2022-01-15
  • 3 回答
  • 0 關(guān)注
  • 222 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號