> ## Content Index
> Fetch the complete content index at: https://blog.anthea.day/llms.txt
> Use this file to discover other available public pages before exploring further.

# 不透過 Factory 實作的 Decorator
- URL: https://blog.anthea.day/dotnet-decorator/
- Published: 2022-10-29T12:13:05.000Z
- Updated: 2026-11-07T14:57:13.000Z
- Author: Anthea / 芫荽
- Tags: #Migrated-1792241843742, #Import 2026-10-17 12:57, Coding, .NET

一般來說，我們會把在程式中，呼叫外部 API 的地方包成 Proxy，透過 Service 進行呼叫，像下面這樣：

```C#
public class PicService
{
    private readonly IPicProxy _picProxy;

    public PicService(IPicProxy picProxy)
    {
        _picProxy = picProxy;
    }

    public void Get()
    {
        _picProxy.Get();
    }
}

public interface IPicProxy
{
    void Get();
}

public class PicProxy : IPicProxy
{
    public void Get()
    {
        Console.WriteLine("Pic Proxy: Get");
    }
}
```

有時候針對 API 所回應的錯誤訊息，想做出不同的處理，比如重試（Retry），但這件事情不論是放在 Service 中做處理，或是在 Proxy 中處理，都會讓他們做超過一件事，違反單一職責。

因此，這時候就可以透過 Decorator 解決。

---

首先要製造出一個負責處理 Retry 的物件 `PicHandleRetryProxy`：

```C#

public interface IPicProxy
{
    void Get();
}

public class PicProxy : IPicProxy
{
    public void Get()
    {
        Console.WriteLine("Pic Proxy: Get");
    }
}

public class PicHandleRetryProxy : IPicProxy
{
    private readonly IPicProxy _picProxy;

    public PicHandleRetryProxy(IPicProxy picProxy)
    {
        _picProxy = picProxy;
    }

    public void Get()
    {
        Console.WriteLine("Pic Handle Retry Proxy: Get");
        _picProxy.Get();
    }
}
```

要注意如果是使用一般的方式來注入 `PicHandleRetryProxy` 會出現 Exception：

```
// A circular dependency was detected for the service of type 'ConsoleApp.IPicProxy'.services.AddSingleton<IPicProxy, PicHandleRetryProxy>();
```

所以要在注入的地方指定 `PicHandleRetryProxy` 的 Interface 要注入誰：

結果：

![](https://blog.anthea.day/content/images/2026/10/1-ljospqchv-u1ljf5xovrsg.png)