# Using Both (Extend & Override)

You’re not limited to just one approach—**you can combine overriding existing methods and adding new ones in a single custom cache service**.\
This gives you full flexibility:

* **Override** methods to change or enhance built-in behavior.
* **Extend** by introducing brand new methods that fit your project’s unique needs.

For example, you can override `SetAsync` to add logging or custom serialization, while also introducing a brand new method like `RemoveAllByPrefix`.\
This is the power of REN.Kit’s design: your cache service can be as standard or as custom as you want.

{% hint style="success" %}
## **Tip:**

Just inherit from the base cache service (like `RENInMemoryCacheService`), override any method you need, and add your own new methods—all in the same class!
{% endhint %}

***

## How to Use Both?

### 1. Create a New Service Interface to Implement New Method

```csharp
public interface IExtendedRENInMemoryCacheService : IRENCacheService
{
    void AdditionalMethod();
}
```

This interface introduces new method while keep using the default ones

***

### **2. Create a New Service to Implement New Method**

```csharp
public class ExtendedAndOverridedRENInMemoryCacheService(IMemoryCache memoryCache) 
    : RENInMemoryCacheService(memoryCache), IExtendedRENInMemoryCacheService
{
    public void AdditionalMethod()
    {
        Console.WriteLine("ExtendedAndOverridedRENInMemoryCacheService AdditionalMethod called.");
        // Implement your additional logic here
    }

    public override void Set<T>(string cacheKey, T data, TimeSpan? absoluteExpiration = null, TimeSpan? slidingExpiration = null)
    {
        Console.WriteLine("ExtendedAndOverridedRENInMemoryCacheService Set called.");
        // You can add custom logic here before calling the base method
        base.Set(cacheKey, absoluteExpiration, slidingExpiration);
    }
}
```

***

### 3. **Register Your Custom Implementation**

Since you are not using the default interface now (you've introduced new method and this method should be taken into account) You should register interface and classes like:

```csharp
builder.Services.AddRENCaching<IExtendedRENInMemoryCacheService, ExtendedAndOverridedRENInMemoryCacheService>(RegisterRENCaching.CacheType.InMemory);
```

Here’s how the registration method works under the hood:

```csharp
public static void AddRENCaching<TICacheService, TCacheService>(this IServiceCollection services, CacheType cacheType)
     where TICacheService : class, IRENCacheService
     where TCacheService : class, TICacheService
 {
     switch (cacheType)
     {
         case CacheType.InMemory:
             AddInMemoryRENCache<TICacheService, TCacheService>(services);
             break;
         case CacheType.Redis:
             AddRedisRENCache<TICacheService, TCacheService>(services);
             break;
         default:
             throw new ArgumentOutOfRangeException(nameof(cacheType), cacheType, null);
     }
 }
```

***

### 4. Use Custom Service In Action

```csharp
[Route("api/[controller]")]
[ApiController]
public class ExtendedAndOverridedInMemoryCacheController(IExtendedRENInMemoryCacheService cacheService) : ControllerBase
{
    [HttpGet("additional-method")]
    public IActionResult AdditionalMethod(string key)
    {
        cacheService.AdditionalMethod();
        return Ok();
    }

    [HttpPost("set")]
    public async Task<IActionResult> SetCache([FromQuery] string key, [FromBody] object value)
    {
        cacheService.Set(key, value, TimeSpan.FromMinutes(10));
        return Ok("Value cached.");
    }
}
```
