First Problem:
services.AddMemoryCache(); // in Startup config
public class AController
{
public AController(IMemoryCache cacheA) { }
}
public class BController
{
public BController(IMemoryCache cacheB) { }
}
problem is that cacheA is the same as cacheB
i'd like to have private API (cluster connections) and public API (exposed to frontend)
how to separate them while keeping it all DI pattern friendly?
Second problem;
i want to have a service that requests some external webserver via HTTP
and its results would be cached in that service, also stored in DB
so we first query localCache then query DB then query external server
results from that service would be used in Controllers and sent to frontend
How to implement such thing with all the fancy asp.netcore patterns?
cache must be the ONE(singleton) so we dont waste DB requests
? adding such Service as services.SCOPED<> but then how to keep it its cache same for every instance (some singleton DI? or static MemoryCache instance?)
i have no idea, no damn idea begging for help
in node.js i would have done it all in a couple of minutes, but its Microsoft hey
Define two cache interfaces:
public interface IPrivateMemoryCache: IMemoryCache
{
}
public interface IPublicMemoryCache: IMemoryCache
{
}
public class AController
{
public AController(IPrivateMemoryCache cacheA) { }
}
public class BController
{
public BController(IPublicMemoryCache cacheB) { }
}
Now you can define different instantiation rules for your IoC container.
Related
I have a very strange situation. I have a UOW Repository pattern. I have domain layer which houses my entities, A Data Access layer which contains the dbcontext (UnitofWork) and repositories for different entities. I have an application layer where i have services which i call for reading and writing data. Architecture contains basically this with some DTOs to help consistency in data. I have a UI layer with MVC5 where i have injected all the dependencies through Unity and it works great if i instantiate each service from a controller constructer.
I have quiet a few services such as GlobalAppSvc (Implemented from IGlobalAppSvc), SystemSettingAppSvc (ISystemSettingAppSvc) etc etc. To make life easier I've created a class called ApplicationManager like this.
public class ApplicationManager
{
public ApplicationManager(ISystemSettingAppSvc systemSettingAppSvc, IBalanceAppSvc balanceAppSvc, IGlobalAppSvc globalAppSvc, IProfileAppSvc profileAppSvc)
{
SystemSettingAppSvc = systemSettingAppSvc;
BalanceAppSvc = balanceAppSvc;
GlobalAppSvc = globalAppSvc;
ProfileAppSvc = profileAppSvc;
}
public ISystemSettingAppSvc SystemSettingAppSvc { get; set; }
public IBalanceAppSvc BalanceAppSvc { get; set; }
public IGlobalAppSvc GlobalAppSvc { get; set; }
public IProfileAppSvc ProfileAppSvc { get; set; }
}
In my Unity i have Registered all the Services and Repositories along with the Unit of Work
container.RegisterType<IUnitOfWork, WUnitOfWork>(new PerResolveLifetimeManager(), new InjectionConstructor());
container.RegisterType<IWUnitOfWork, WUnitOfWork>(new PerResolveLifetimeManager(), new InjectionConstructor());
I have created a BaseController by extending Controller so that i don't have to resolve Application manager in every controller i write. In base controller i am resolving this ApplicationManager as
public class BaseController : Controller
{
// GET: Base
public ApplicationManager ApplicationManager
{
get;
private set;
}
public BaseController()
{
ApplicationManager = UnityConfig.Container
.Resolve<ApplicationManager>();
}
}
I can then go in any controller and extend the controller with this BaseController and i have access to ApplicationManager.GlobalAppSvc.Methods()...
My problem is that whenever there is a data modification such as lets say there is an action which executes to deduct the balance and save changes for a particular user. When i request the user's balance again it is still showing unchanged balance however the balance in Database is deducted but the service is not fetching the updated data. What am i doing wrong?
It looks like the solution is to ensure the BalanceAppSvc needs to be registered with Unity as such:
ApplicationManager=UnityConfig.Container.Resolve<ApplicationManager>(); and registering types as container.RegisterType<IBalanceAppSvc, BalanceAppSvc>(new PerResolveLifetimeManager());
Hy i wrote a couple of shared services in my prism application.
I´m now at the point where i want to chain my servces. I want to use the services in another service. For example i want to use mit Loggerservice to log errors not only in my ViewModel, but also in the other Services.
Is that possible in a better way than i do now?
Now i´m requesting both services in my ViewModels constructor.
Than i call a method of service one and give them a reference to the service two as a parameter.
I think there is a better way of doing this in Prism?!
Thanks
In general yes you can register and reuse services within other services. For example you could have:
public interface ILogger
{
void Log(string message);
}
public interface IApiService
{
Task DoStuff();
}
public class ApiService : IApiService
{
ILogger _logger { get; }
public ApiService(ILogger logger)
{
_logger = logger
}
public Task DoStuff()
{
// Do DoStuff
_logger.Log("Some Message");
}
}
You however should not attempt to use INavigationService within your services as the NavigationService requires an understanding of which Page you are navigating from to work correctly.
I have an asp.net website and I would like to organize it into three layers
DataAccess
Domain
UI
What specifically goes in each of these layers?
e.g
Data
- Models
- Repositories? Would that be just interfaces
- IoC?
Domain
- Services?
UI
- javascript
- Area specific models?
- css
Could someone provide a simple guideline for organizing an asp.net website like this?
As other people have said each situation is different, but for a basic architecture, I would probably go along with something like this. It has gotten me out of a few jams and up and running quite quickly.
Infrastructure Layer
This is where all the data access is done. Database connection management, etc.
The Repositories include all queries to the database.
The Dependency Resolution sits here too. Use your DI Container of choice.
Domain Layer
This is where all you business logic sits.
The Domain Services Interfaces are what the UI layer call to use your business logic
UI
Pretty obvious this one....
Code Example
--UI
public class MyController
{
private readonly IMySerivce _myService;
public MyController(IMySerivce myService)
{
_mySerivce = myService;
}
public void MyAction()
{
_myService.DoSomeAction();
}
}
--Domain
public Interface IMyService()
{
void DoSomeAction();
}
public class MySerivce : IMyService()
{
private readonly IMyRepository _myRespository;
public MySerivce(IMyRepository myRepository)
{
_myRepository = myRepository;
}
public void DoSomeAction()
{
_myRepository.Save();
}
}
public interface IMyRepository
{
void Save();
}
--DataLayer
public MyRepository : IMyRepository
{
public void Save()
{
//Manage Save here
}
}
Additionally I usually have a separate area for unit/integration tests.
Update
This most definitely is dependent on your situation. It is very hard to say what method is best without fully understanding what you are ultimately trying to build.
From the list below you can see which method works well for you or fits well with your architecture.
Regardless of which one you choose, your Repository Implementation will have to have a dependency on your Domain Objects project.
Some techniques in doing it include:
No Mapping
Your Domain Objects really then become dummy mappings to your tables. i.e. have a table in your database call User. Then have a Domain Object called User. This is by far the simplest technique.
--Domain
public class User
{
public int Id {get; set;}
public string UserName {get; set;}
public string FirstName {get; set;}
public string LastName {get; set;}
public string Password {get; set;}
}
--Infrastructure
public class UserRepository : IUserRepository
{
public Core.User GetById(int id)
{
return DBConnection.GetByIdQuery(id);
}
}
Mapping
Martin Fowler describes it here
It is possible in your infrastructure layer to have what are known as Domain Transfer Objects (DTO) that represent your database tables. Similar to above, a table called User, a DTO called User. Both having the same properties.
Your domain Entity then becomes a true representation of your domain and business logic.
The mapping of the DTO to your Domain Entity (search query) can be done in the Repository and the mapping of your Domain Entity to your DTO (save/update query) would also be done in your Repository.
To do your mapping you can either create custom mapping classes or use 3rd party tools like AutoMapper. I am a big fan of AutoMapper.
A sample code example would be along the lines of:
--Custom mapper
public class UserRepository : IUserRepository
{
private readonly IUserMapper _userMapper;
public UserRepository(IUserMapper userMapper)
{
_userMapper = userMapper;
}
public Domain.User GetUserById(int id)
{
var DtoUser = GetUserByIdQuery(int id);
return _userMapper.MapUserDTOToDomainEntity(DtoUser);
}
}
public class UserMapper : IUserMapper
{
public Domain.User MapUserDTOToDomainEntity(DataEntity.User dtoUser)
{
//Manual property mapping
}
}
--AutoMapper Example
public class UserRepository : IUserRepository
{
public Domain.User GetUserById(int id)
{
var DtoUser = GetUserByIdQuery(int id);
return Mapper.Map<Domain.User>(DtoUser);
}
}
Other examples include:
https://stackoverflow.com/questions/14724612
There are many many debates out there in blogs and here on SO about the value of DTO's,
including MSDN, this blog and these https://stackoverflow.com/questions/11237946, https://stackoverflow.com/questions/15148866
I have the following code in my ASP.NET project
public sealed class IoC
{
private static readonly IDependencyResolver resolver =
Service.Get("IDependencyResolver") as IDependencyResolver;
static IoC()
{
}
private IoC()
{
}
public static IDependencyResolver Container
{
get
{
return resolver;
}
}
}
public static class Service
{
public static object Get(string serviceName)
{
// Code to create and return instance...
}
}
Is IoC.Container going to be thread safe?
Initialization of static fields is thread-safe: that is, the .NET runtime guarantees that your field will be initialized only once in the program, no matter how many threads access it and in what order.
As Andrey points out, the Service.Get method itself needs to be thread-safe.
IoC itself looks ok, but the whole structure will not be thread-safe if resolver is not thread safe. If you want to have resolver per thread you can use attribute [ThreadStatic]
I see tons of material on how to inject services using the ControllerBuilder.Current.SetControllerFactory but what if I wanted to resolve my services in the model? Would I have to get them from the Controller layer and pass them up?
Ideally you should not be injecting services into the model as this would require you to register your model with the container.
If you need to use a service within a model instance, pass the service in as a method argument and then you can inject the service into the controller.
Without knowing more about the scenario it is hard to give clearer advice, however the following outline may help:
public interface IService
{
// ... describe the contract the service must fulfill
}
public class Model
{
public void DoSomething( IService service )
{
// ... do the necessary work using the service ...
}
}
public class AController : Controller
{
private readonly IService _injectedService;
public AController( IService injectedService )
{
_injectedService = injectedService;
}
public ActionResult SomeAction( int modelId )
{
// ... get the model from persistent store
model.DoSomething( _injectedService );
// ... return a view etc
}
}