I have a set of componentes registered to StructureMap. What should be the best way to resolve a component depending on the actual Tenant?
Small example:
There are two tenants, say, Yellow and Green.
I have an IValidator that has two implementations: YellowValidator and GreenValidator.
Say the application is MVC and that the tentant comes form the URL.
So, I just need the proper IValidator to be injected depending on the tenant.
I've seen many solutions for multi-tenant applications that deals only with multitenancy of data, normaly configuring different databases depending on the tenant. That involves only parameter passing. But this is the case where variation occurs in behavior, not in data. I want the IoC container to Resolve the right instance transparently.
EDIT: more info:
The IValidator interface have a simple method bool Validate(), but the implementation require some injection.
There are other custom validators, but they are used by both tenants.
There is a clear tentant strategy based on the URL. This means that each request can have a different tenant, and that a single application serves both tenants.
There are many ways to skin a cat. It's hard for me to guess the design of your application, so here is an idea. Things that come in mind are to hide validators behind a composite, to allow users of the IValidator interface to know nothing about having many implementations. Such composite can look like this:
public class ValidatorComposite : IValidator
{
private IEnumerable<IValidator> validators;
public ValidatorComposite(
IEnumerable<IValidator> validators)
{
this.validators = validators;
}
public bool Validate(object instance)
{
return this.validators.All(v => v.Validate(instance));
}
}
You can create multiple composites and register them by key where the key is the name of the tenant (but without keyed registrations is probably just as easy). Those composites can be wrapped in yet another composite that will delegate to the proper tenant-specific composite. Such a tenant-selecting composite could look like this:
public class TenantValidatorComposite : IValidator
{
private ITenantContext tenantContext;
private IValidator defaultValidator;
private IDictionary<string, IValidator> tenantValidators;
public ValidatorComposite(
ITenantContext tenantContext,
IValidator defaultValidator,
IDictionary<string, IValidator> tenantValidators)
{
this.tenantContext = tenantContext;
this.defaultValidator = defaultValidator;
this.tenantValidators = tenantValidators;
}
public bool Validate(object instance)
{
string name = this.tenantContext.CurrentTenant.Name;
return this.defaultValidator.Validate(instance) &&
this.tenantValidators[name].Validate(instance);
}
}
The ITenantContext is an abstraction that allows you to get the current tenant within the current context. You probably already have something like that in place, but I imagine an implementation to look something like this:
class UrlBasedTenantContext : ITenantContext
{
public Tenant Current
{
get
{
// Naive implementation.
if (HttpContext.Current.Request.Url.Contains("tenant1"))
{
return Tenant1;
}
return Tenant2;
}
}
}
Create a TenantValidatorComposite would be easy:
var defaultValidator = CompositeValidator(
GetAllDefaultValidators());
var tenantValidators = new Dictionary<string, IValidator>()
{
{ "tenant1", new CompositeValidator(GetValidatorsFor("tenant1")) },
{ "tenant2", new CompositeValidator(GetValidatorsFor("tenant2")) },
};
var tenantValidator = new TenantValidatorComposite(
new UrlBasedTenantContext(),
defaultValidator,
tenantValidators);
I hope this helps.
Related
I often need a class/service that will give me some data trough fetching it from a DB, transforming an existing data structure or do both internally but I sometimes have a difficulty naming them properly.
I am currently working with Sylius and they are using classes/services with suffixes such as Checker, Applicator, Processor... I have clear understanding of these names and their implications as to what and how they are doing things. But there are also suffixes Provider and Resolver and I have a difficulty differentiating between them. I don't understand the exact differences of their naming.
What I observed is:
Provider: fetching data that are not yet available (internally fetching data from DB or external API)
Resolver: I already have a bunch of data (and I don't need any additional data) and I need to filter, transform or get some subset of it.
Is there some convention or design pattern to names Resolver and Provider? Am I somewhat right here? Or is there more nuance to this naming?
In my view, patterns are not depend on technology or language, so this article can be applied here:
Content Providers provide an interface, e.g. for publishing and consuming data
and:
Content Resolver resolves a publishing and consuming data to a specific Content provider.
The Content Resolver includes the CRUD (create, read, update, delete) methods corresponding to the abstract methods (insert, query, update, delete) in the Content Provider class.
UPDATE
Provider is an abstraction that can be implemented by concrete providers. E.g., there is DataProvider and DataProvider is an abstraction. So we want concrete implementations of SqlServerProvider, PostgreProvider, OracleProvider.
Let me show an example via C#:
public interface IDataProvider
{
string GetById();
}
public class SqlServerProvider : IDataProvider
{
public string GetById()
{
return "Data retrieved with SqlServerProvider";
}
}
public class PostgreProvider : IDataProvider
{
public string GetById()
{
return "Data retrieved with PostgreProvider";
}
}
public class OracleProvider : IDataProvider
{
public string GetById()
{
return "Data retrieved with OracleProvider";
}
}
Then we need to resolve the above dependenies to use them. But how? We can create DataResolver:
public enum DataProviderType
{
SqlServer, Posgre, Oracle
}
public class DataResolver
{
private Dictionary<DataProviderType, IDataProvider> _dataProviderByType =
new Dictionary<DataProviderType, IDataProvider>()
{
{ DataProviderType.SqlServer, new SqlServerProvider() },
{ DataProviderType.Posgre, new PostgreProvider() },
{ DataProviderType.Oracle, new OracleProvider() },
};
public IDataProvider Resolve(DataProviderType dataProviderType)
{
return _dataProviderByType[dataProviderType];
}
}
and then we can run the above code like this:
DataResolver dataResolver = new DataResolver();
string someValue = dataResolver.Resolve(DataProviderType.SqlServer).GetById();
Console.WriteLine(someValue); // OUTPUT: Data retrieved with SqlServerProvider
See more examples of code here
The main WebServerExtension example from the JUnit5 manual is incomplete and it doesn't fully show how to properly store the configuration (e.g. enableSecurity, server url).
https://github.com/junit-team/junit5/blob/master/documentation/src/main/java/example/registration/WebServerExtension.java
The example ignores or hard codes the values. The manual (section 5.11. Keeping State in Extensions) implies that the "Store" should be used but the ExtensionContext is not yet available yet when the object is constructed -- its not clear how to handle migrating this data to the Store as the ExtensionContext is not yet available in the constructor.
Also its not clear to me that using the Store API for the WebServerExtension programmatic example is even desirable and perhaps it could work just using the internal state (e.g. this.serverUrl, this.enableSecurity, etc.).
Maybe the Store is more applicable to Extensions which don't use this "programmatic" style where multiple instances of the custom extension may exist (appropriately)? In other words its not clear to me from the guide if this a supported paradigm or not?
Other JUnit 5 extension examples online (e.g. org.junit.jupiter.engine.extension.TempDirectory) show how to leverage annotations to handle passing configuration info to the Store but it would be nice if there were a complete programmatic builder type example like WebServerExtension too.
Examples like TempDirectory clearly have access to the ExtensionContext from the beforeXXX() methods whereas the WebServerExtension example does not.
Using the following approach below seems to work fine but I wanted confirmation that this is a supported paradigm (i.e. using fields instead of Stores when using this programmatic approach).
public class WebServerExtension implements BeforeAllCallback {
private final boolean securityEnabled;
private final String serverUrl;
public WebServerExtension(Builder builder) {
this.securityEnabled = builder.enableSecurity;
this.serverUrl = build.serverUrl;
}
#Override
public void beforeAll(ExtensionContext context) {
// is it ok to use this.securityEnabled, this.serverUrl instead of Store API???
}
public String getServerUrl() {
return this.serverUrl;
}
public boolean isSecurityEnabled() {
return this.securityEnabled;
}
public static Builder builder() {
return new Builder();
}
public static class Builder {
private boolean enableSecurity;
private String serverUrl;
public Builder enableSecurity(boolean b) {
this.enableSecurity = b;
return this;
}
public Builder serverUrl(String url) {
this.serverUrl = url;
return this;
}
public WebServerExtension build() {
return new WebServerExtension(this);
}
}
}
Thanks!
I have an ASP .Net Core 2.2. Web API. I'd like to speed up performance by using MemoryCache. However, I need to cache 2 different types, both which use integer keys. The one type is a list of users and the other is a list of groups.
Now, I'm adding the MemoryCache service in the Startup.cs file:
services.AddMemoryCache();
and then I'm using dependency injection to access this cache in two different places (in Middleware and in a service I wrote).
From what I understand, both these caches are the same instance. So when I add my various users and groups to it, since they both have integer keys, there will be conflicts. How can I handle this? I thought about using two caches - one for each type - but (a) I'm not sure how to do this and (b) I've read somewhere that it's not recommended to use multiple caches. Any ideas?
Yeah, I've had the same issue before and resorted to creating an extended version of the MemoryCache that allows me to plug in different "stores".. You can do it simply by wrapping the data you're sticking into the cache in a "metadata" type class. I suppose similar to how the ServiceDescriptors wrap your service registrations in the DI?
Also, in specific answer to the point "I thought about using two caches - one for each type". This is where the problem will arise because I believe IMemoryCache gets registered as a singleton by default
I ran into this problem myself. One solution I thought of was to just two instantiate separate memory caches in a wrapper class and register the wrapper class as a singleton instance. However, this only makes sense if you have different requirements for each memory cache and/or you expect to store a massive amount of data for each memory cache (at that point, an in-memory cache may not be what you want).
Here is some example classes I want to cache.
// If using a record, GetHashCode is already implemented through each member already
public record Person(string Name);
// If using a class, ensure that Equals/GetHashCode is overridden
public class Car
{
public string Model { get; }
public Car(string model)
{
Model = model;
}
public override bool Equals(object? obj)
{
return obj is Car car &&
Model == car.Model;
}
public override int GetHashCode()
{
return HashCode.Combine(Model);
}
}
Here is a dual MemoryCache implementation.
public class CustomCache : ICustomCache // Expose what you need and register it as singleton instance
{
private readonly MemoryCache personCache;
private readonly MemoryCache carCache;
public CustomCache(IOptions<MemoryCacheOptions> personCacheOptions, IOptions<MemoryCacheOptions> carCacheOptions)
{
personCache = new MemoryCache(personCacheOptions);
carCache = new MemoryCache(carCacheOptions);
}
public void CreatePersonEntry(Person person)
{
_ = personCache.Set(person, person, TimeSpan.FromHours(1));
}
public void CreateCarEntry(Car car)
{
_ = carCache.Set(car, car, TimeSpan.FromHours(12));
}
}
If you don't have the above requirements, then you could just do what juunas mentioned and create an easy wrapper with a composite key. You still need to ensure GetHashCode is properly implemented for each class you want to store. Here, my composite key is just an integer (I used prime numbers, no specific reason) paired with an object. I didn't use a struct for the key as the MemoryCache uses a Dictionary<object, CacheEntry>, so I don't want to box/unbox the key.
public class CustomCache : ICustomCache // Expose what you need
{
private readonly IMemoryCache cache;
public CustomCache(IMemoryCache cache)
{
this.cache = cache;
}
public void CreatePersonEntry(Person person)
{
_ = cache.Set(CustomKey.Person(person), person, TimeSpan.FromHours(1));
}
public void CreateCarEntry(Car car)
{
_ = cache.Set(CustomKey.Car(car), car, TimeSpan.FromHours(12));
}
private record CompositeKey(int Key, object Value)
{
public static CustomKey Person(Person value) => new(PERSON_KEY, value);
public static CustomKey Car(Car value) => new(CAR_KEY, value);
private const int PERSON_KEY = 1123322689;
private const int CAR_KEY = 262376431;
}
}
Let me know if you see anything wrong, or if there is a better solution.
Looking for some guidance in designing my new MVC 4 app.
I would like to have a url parameter s=2011 on every page of the app to let me know what year of data I'm working with. Obviously, the user will have a way to change that parameter as needed.
I will need that parameter in every controller and wondering the best way to do this. I was thinking of creating a base controller that reads Request.QueryString and puts the year into a public property. However, considering all the extensability points in MVC, I'm wondering if there's a better way to do this?
This very much depends on the design of your app, but just to give you two alternatives
IActionFilter
If you are doing data context per request you can use a global IActionFilter to hook pre-action execution globally and apply a query filter to your data context behind the scenes.
Major down-side of this is that to test the controller you will need to have the full MVC pipeline setup so that the actionfilter gets applied properly.
Dependency Injection
Instead of using sub-classing (base controller as you say) you can use dependency injection . Keeping things more loose will allow you to pull the filter from query string, cookie, user setting in the database or whatever else - without your controller knowing where it comes from.
Here is some pseudo code how I would do it if I was using something like Entity Framework or Nhibernate (also I am sure applicable with other technologies as well)
public Car
{
public string Year { get; set; }
}
public class CarsDataContext : DbContext
{
private IQuerable<Cars> _cars = null;
private Func<Car, bool> _carsFilter = null;
public IQuerable<Car> Cars {
get {
if (_carsFitler != null)
return _cars.Where(_carsFitler);
return _cars;
}
set { _cars = value; }
}
public void ApplyCarsFilter(Func<Car, bool> predicate)
{
_carsFilter = predicate;
}
}
Assuming you have dependency injection setup already (NInject or whichever other framework) in you can configure how the context to be intialized
Bind<CarsDataContext>().ToMethod(() => {
string yearFilter = GetYearFilter(); // can be coming from anywhere
CarsDataContext dataContext = new CarsDataContext();
dataContext.Applyfilter(car => car.Year == yearFilter);
return dataContext;
}).InRequestScope();
Then my controller knows nothing about the data filtering and I can easily test it:
class MyController : Controller
{
public MyController(CarsDataContext dataContext)
{
}
...
}
However I would only do this is filtering the dataset was across many controllers and important part of my software. Otherwise it's pure over-engineering.
So I've been learning about the Repository model, and it seems that it is expected that Repositories do not do a lot of intricate logic. However I also read that most of the business logic should not be inside of my Controllers. So where do I put it?
I've looked at some sample applications and it seems that they have another layer called Services that do more intricate logic for things. So how does this factor into the MVC pattern?
Do I want to build my services to access my repositories, and then my controllers to access my services? Like this?
interface IMembershipService
{
bool ValidateUser(string username, string password);
MembershipCreateStatus Create(string username, string password);
}
interface IMembershipRepository
{
MembershipCreateStatus Create(string username, string password);
}
class MembershipRepository : IMembershipRepository
{
public MembershipRepository(ISession session)
{
**// this is where I am confused...**
}
}
class MembershipService : IMembershipService
{
private readonly IMembershipRepository membershipRepository;
public MembershipService(IMembershipRepository membershipRepository)
{
this.membershipRepository = membershipRepository;
}
public bool ValidateUser(string username, string password)
{
// validation logic
}
public MembershipCreateStatus Create(string username, string password)
{
return membershipRepository.Create(username, password);
}
}
class MembershipController : Controller
{
private readonly IMembershipService membershipService;
public MembershipController(IMembershipService membershipService)
{
this.membershipService = membershipService
}
}
The marked part of my code is what confuses me. Everything I have read said I should be injecting my ISession into my repositories. This means I could not be injecting ISession into my services, so then how do I do Database access from my Services? I'm not understanding what the appropriate process is here.
When I put ValidateUser in my IMembershipRepository, I was told that was 'bad'. But the IMembershipRepository is where the database access resides. That's the intention, right? To keep the database access very minimal? But if I can't put other logic in them, then what is the point?
Can someone shed some light on this, and show me an example that might be more viable?
I am using Fluent nHibernate, ASP.NET MVC 3.0, and Castle.Windsor.
Should I instead do something like ...
class MembershipService
{
private readonly IMembershipRepository membershipRepository;
public MembershipService(ISession session)
{
membershipRepository = new MembershipRepository(session);
}
}
And never give my Controllers direct access to the Repositories?
Everything I have read said I should be injecting my ISession into my repositories.
That's correct. You need to inject the session into the repository constructor because this is where the data access is made.
This means I could not be injecting ISession into my services, so then how do I do Database access from my Services?
You don't do database access in your services. The service relies on one or more repositories injected into its constructor and uses their respective methods. The service never directly queries the database.
So to recap:
The repository contains the simple CRUD operations on your model. This is where the data access is performed. This data access doesn't necessary mean database. It will depend on the underlying storage you are using. For example you could be calling some remote services on the cloud to perform the data access.
The service relies on one or more repositories to implement a business operation. This business operation might depend on one or more CRUD operations on the repositories. A service shouldn't even know about the existence of a database.
The controller uses the service to invoke the business operation.
In order to decrease the coupling between the different layers, interfaces are used to abstract the operations.
interface IMembershipService
{
bool ValidateUser(string username, string password);
MembershipCreateStatus Create(string username, string password);
}
Creating a service like this an anti-pattern.
How many responsibilities does a service like this have? How many reasons could it have to change?
Also, if you put your logic into services, you are going to end up with an anemic domain. What you will end up with is procedural code in a Transaction Script style. And I am not saying this is necessarily bad.
Perhaps a rich domain model is not appropriate for you, but it should be a conscious decision between the two, and this multiple responsibility service is not appropriate in either case.
This should be a HUGE red flag:
public MembershipCreateStatus Create(string username, string password)
{
return membershipRepository.Create(username, password);
}
What is the point? Layers for the sake of layers? The Service adds no value here, serves no purpose.
There are a lot of concepts missing.
First, consider using a Factory for creating objects:
public interface IMembershipFactory {
MembershipCreateStatus Create(string username, string password);
}
The factory can encapsulate any logic that goes into building an instance or beginning the lifetime of an entity object.
Second, Repositories are an abstraction of a collection of objects. Once you've used a factory to create an object, add it to the collection of objects.
var result = _membershipFactory.Create("user", "pw");
if (result.Failed); // do stuff
_membershipRepository.Add(status.NewMembership); // assumes your status includes the newly created object
Lastly, MyEntityService class that contains a method for every operation that can be performed on an Entity just seems terribly offensive to my senses.
Instead, I try to be more explicit and better capture intent by modeling each operation not as a method on a single Service class, but as individual Command classes.
public class ChangePasswordCommand {
public Guid MembershipId { get; set; }
public string CurrentPassword { get; set; }
public string NewPassword { get; set; }
}
Then, something has to actually do something when this command is sent, so we use handlers:
public interface IHandle<TMessageType> {
void Execute(TMessageType message);
}
public class ChangePasswordCommandHandler : IHandle<ChangePasswordCommand> {
public ChangePasswordCommandHandler(
IMembershipRepository repo
)
{}
public void Execute(ChangePasswordCommand command) {
var membership = repo.Get(command.MembershipId);
membership.ChangePassword(command.NewPassword);
}
}
Commands are dispatched using a simple class that interfaces with our IoC container.
This helps avoids monolithic service classes and makes a project's structure and location of logic much clearer.