I'm trying to figure out where to put my utility classes in a DDD based project. The case is a follows:
I have a class called CookieAwareWebClient which is required for the core to work. Form what I've read online this seems like a class that belongs in the Infrastructure tier, however one is not supposed to refer to the Infrastructure tier from the Core tier. This means that I cannot place functionality that the Core tier depends on in the Infrastructure tier. Where then should this CookieAwareWebClient class be placed?
Without understanding exactly what you need to do, I believe that #plalx sums it up in the comments:
Establish an interface which provides the functionality that your Core tier requires
Implement this interface in CookieAwareWebClient
Use Dependency Inversion to allow the Core to use CookieAwareWebClient
Here's some code (C# in this case) with constructor injection as an example:
The interface:
namespace Core
{
public interface IBlah
{
int SomethingCoreNeeds();
}
}
The implementation by CookieAwareWebClient:
namespace Services
{
public class CookieAwareWebClient : IBlah
{
// ... rest of class
private int _somethingCookieAwareWebClientHasThatCoreNeeds;
public int SomethingCoreNeeds()
{
return _somethingCookieAwareWebClientHasThatCoreNeeds;
}
// ... rest of class
}
}
The consuming service in your Core:
namespace Core
{
public class DomainService
{
private readonly IBlah _blah;
public DomainService(IBlah blah)
{
_blah = blah;
}
public void DoSomething(DomainEntity entity)
{
entity.NeededValue = _blah.SomethingCoreNeeds();
}
}
}
Related
I have an existing program with some plugin infrastructure that currently relies on plugin classes having parameterless constructors. I'd like to offer plugin authors the opportunity to just require some infrastructure from my program by specifying parameters for the constructor.
Internally, I use some generic wrapper class to encapsulate the plugin's classes and to make them behave to the rest of my program like older pre-plugin era internal classes.
I have some placeholder here representing my infrastructure:
public interface IInfrastructure
{
}
public class Infrastructure : IInfrastructure
{
}
Some plugin interface specification:
public interface IPlugin
{
}
the plugin implementation requiring my infrastructure:
public class Plugin : IPlugin
{
public Plugin(IInfrastructure _)
{
}
}
and my generic wrapper class expecting some plugin class
public class PluginWrapper<TImpl> where TImpl: class, IPlugin
{
public PluginWrapper(TImpl _)
{
}
}
After registering the involved types:
ServiceLocator.Default.RegisterType<IInfrastructure, Infrastructure>(RegistrationType.Transient);
ServiceLocator.Default.RegisterType(typeof(Plugin),typeof(Plugin), RegistrationType.Transient);
var wrapperType = typeof(PluginWrapper<>).MakeGenericType(typeof(Plugin));
ServiceLocator.Default.RegisterType(wrapperType, wrapperType,RegistrationType.Transient);
I find out that I can resolve the "inner" plugin type:
Assert.NotNull(ServiceLocator.Default.ResolveType<Plugin>());
but I can't resolve the "Wrapper" type.
Assert.NotNull(ServiceLocator.Default.ResolveType<PluginWrapper<Plugin>>());
Am I hitting a limitation of Catel's IoC container, or am I doing something wrong?
When not using the generic registration method, I passed the registration type in the position of the "tag" parameter by accident.
So, changing the registration part to this version:
ServiceLocator.Default.RegisterType<IInfrastructure, Infrastructure>(RegistrationType.Transient);
ServiceLocator.Default.RegisterType(typeof(Plugin),typeof(Plugin),registrationType:RegistrationType.Transient);
var wrapperType = typeof(PluginWrapper<>).MakeGenericType(typeof(Plugin));
ServiceLocator.Default.RegisterType(wrapperType, wrapperType, registrationType:RegistrationType.Transient);
fixes the problem and everything goes as expected.
Does it make sense to create another layer over the EF6 - Repository/UnitOfWork ?
In our custom repository we can add specific queries like GetTopXXX, GetLastUpdated, etc.
Bu we can do the same in Business Logic with LINQ on DBContext.
I would highly recommend to use a repository to separate the logic that retrieves the data in your situation.
Using the Repository pattern, very briefly, you will implement all your queries such as add, edit, update defined in your interface. And the way which you interact with the database is using Entity Framework.
public interface IProductRepository
{
void Add(Product product);
}
public class ProductRepository : IProductRepository
{
private readonly DbContenxt _dbContext;
public ProductRepository(DbContext dbContext)
{
_dbContext = dbContext;
}
public void Add(Product product)
{
var product = new Product() { Name = "Test" };
_dbContext.Add(product);
_dbContext.SaveChanges();
}
}
I am developing a ASP.NET MVC Project following the Onion Architecture. I have added the Models inside my Core Project and these Models will be referred as the POCO classes for the Entity Framework Models in the Infrastructure Project.
My question is how can I add Data Annotations Which depends on the Entity Framework?
Can I make the Core Models as Interfaces and inherit it in the Infrastructure Projects and do real Implementation?
You don't need to create Core Models as Interfaces if you switch from Data Annotations the Fluent API.
Here's an example.
The Entity1 object is a core layer domain object:
namespace MyApp.Core.Model
{
public class Entity1
{
public short Id { get; set; }
public string ExternalCode { get; set; }
public byte Status { get; set; }
}
}
In the infrastructure layer, create an Entity1Mapping class where you'll do what you'd have done using Data Annotation, but this time, with the Fluent API instead:
using System.Data.Entity.ModelConfiguration;
namespace MyApp.Infrasrtucture.Data.Configuration
{
internal class Entity1Mapping : EntityTypeConfiguration<Core.Model.Entity1>
{
internal Entity1Mapping()
{
HasKey(g => g.Id);
Property(g => g.Id).IsRequired();
Property(g => g.ExternalCode)
.IsRequired()
.HasMaxLength(100)
.IsVariableLength()
.IsUnicode(false);
Property(g => g.Status).HasColumnName("EntityStatus").IsRequired();
}
}
}
Last thing you have to do, is adding the mapping in the modelBuilder of your context:
using System.Data.Entity;
namespace MyApp.Infrastructure.Data
{
public class MyContext : DbContext, IDbContext
{
public MyContext() : base("ConnectionStringMyContext")
{ }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
Database.SetInitializer<MyContext>(null);
modelBuilder.Configurations.Add(new Configuration.Entity1Mapping());
}
}
}
This is the IDBContext just in case:
public interface IDbContext
{
DbSet<T> Set<T>() where T : class;
DbEntityEntry<T> Entry<T>(T entity) where T : class;
int SaveChanges();
void Dispose();
}
Using FluentAPI is a good a solution in my opinion.
It is worth noting though that System.Component.DataAnnotations does not rely on EntityFramework - so you can use DataAnnotations in your core project and still be agnostic on your particular persistance mechanism.
I have a question regarding ServiceStack. Why are there empty Request Classes, why do we have to have a Request Class? For example:
[Route("/test", "GET")]
public class Test
{
}
public class TestResponse
{
public string Date { get; set; }
}
public class TestService : Service
{
public object Get(Test test)
{
return new TestResponse { Date = DateTime.Now.ToString() };
}
}
If I don't pass an object with my request, my service fails?
Then I'm my Global.asax file, I have:
public class AxDataAppHost : AppHostBase
{
public AxDataAppHost() :
base("AxData", typeof(TestService).Assembly)
{
}
}
What if I have more than 1 service, in the example above I'm using TestService but what if I have one for Customers, Orders and Products? How do I handle multiple services?
why do we have to have a Request Class?
ServiceStack is a message-based framework that embraces Martin Fowler's Remote Service Best Practices (i.e. Remote Facade, DTOs and Gateway) which utilizes a ServiceGateway to send coarse-grained Request DTOs which commonly returns a typed Response DTO (though services can return anything). Using a message-based design has many advantages and is what enables ServiceStack's typed end-to-end API.
E.g. you can re-use these types you defined your services with:
public class Test : IReturn<TestResponse> {}
public class TestResponse
{
public string Date { get; set; }
}
On the client, which is what gives you a typed API without code-gen, e.g:
var client = new JsonServiceClient(BaseUri);
TestResponse response = client.Get(new Test());
Note: you don't even need custom routes as by default ServiceStack's C# clients will fallback to use the pre-defined routes (enabled by default).
What if I have more than 1 service, in the example above I'm using TestService but what if I have one for Customers, Orders and Products? How do I handle multiple services?
In your AppHost base constructor you're passing in an assembly (i.e. NOT a single service):
public AxDataAppHost() : base("AxData", typeof(TestService).Assembly) {}
This tells ServiceStack where to look for and wire-up all your services. You only need to do this once for each dll/assembly that your services are in.
ServiceStack's AppHosts also allows specifying multiple assemblies which you can use to wire-up services located in multiple assemblies, e.g:
public AxDataAppHost()
: base("AxData", typeof(TestService).Assembly, typeof(ServiceInNewDll).Assembly) {}
If I have an entity Entity and a service EntityService and EntityServiceFacade with the following interfaces:
interface EntityService {
Entity getEntity(Long id);
}
interface EntityServiceFacade {
EntityDTO getEntity(Long id);
}
I can easily secure the read access to an entity by controlling access to the getEntity method at the service level. But once the facade has a reference to an entity, how can I control write access to it? If I have a saveEntity method and control access at the service (not facade) level like this (with Spring security annotations here):
class EntityServiceImpl implements EntityService {
...
#PreAuthorize("hasPermission(#entity, 'write')")
public void saveEntity(Entity entity) {
repository.store(entity);
}
}
class EntityServiceFacadeImpl implements EntityServiceFacade {
...
#Transactional
public void saveEntity(EntityDTO dto) {
Entity entity = service.getEntity(dto.id);
entity.setName(dto.name);
service.save(entity);
}
}
The problem here is that the access control check happens already after I have changed the name of the entity, so that does not suffice.
How do you guys do it? Do you secure the domain object methods instead?
Thanks
Edit:
If you secure your domain objects, for example with annotations like:
#PreAuthorize("hasPermission(this, 'write')")
public void setName(String name) { this.name = name; }
Am I then breaking the domain model (according to DDD?)
Edit2
I found a thesis on the subject. The conclusion of that thesis says that a good way IS to annotate the domain object methods to secure them. Any thoughts on this?
I wouldn't worry about securing individual entity methods or properties from being modified.
Preventing a user from changing an entity in memory is not always necessary if you can control persistence.
The big gotcha here is UX, you want to inform a user as early as possible that she will probably be unable to persist changes made to that entity. The decision you will need to make is whether it is acceptable to delay the security check until persistence time or if you need to inform a user before (e.g. by deactivating UI elements).
If Entity is an interface, can't you just membrane it?
So if Entity looks like this:
interface Entity {
int getFoo();
void setFoo(int newFoo);
}
create a membrane like
final class ReadOnlyEntity implements Entity {
private final Entity underlying;
ReadOnlyEntity(Entity underlying) { this.underlying = underlying; }
public int getFoo() { return underlying.getFoo(); } // Read methods work
// But deny mutators.
public void setFoo(int newFoo) { throw new UnsupportedOperationException(); }
}
If you annotate read methods, you can use Proxy classes to automatically create membranes that cross multiple classes (so that a get method on a readonly Entity that returns an EntityPart returns a readonly EntityPart).
See deep attenuation in http://en.wikipedia.org/wiki/Object-capability_model for more details on this approach.