Recently I was asked to develop a project. The architecture looks like:
I am going to use DTO objects to pass data between 2nd and 3rd tier.
I have realized that the project will have huge domain model and a lot of business entities should support standart and custom CRUD operations. On the first tier it will be solved by generic NHibernate Repository + Specification.
But 2nd tier (one WCF service) will look like set of methods which provides custom and standart CRUD interface of DTO to 3rd tier.
For example model looks like:
class Product {}
class Category {}
DTOs:
class ProductDTO {}
class CategoryDTO {}
"problem" WCF Service:
public class DataService
{
public List<CategoryDTO> GetAllCategories()
{
}
public List<ProductDTO> GetAllProducts()
{
}
}
possible solution:
public class ProductDataService
{
public List<ProductDTO> GetAllProducts()
{
}
}
public class CategoryDataService
{
public List<CategoryDTO> GetAllCategories()
{
}
}
Questions:
Is there any good alternatives for the solution listed above?
Yes, you can use RESTfull service. I would also recommend against using fat interfaces (mathieu solution). Fat interfaces are hard to maintain, refactor, they are bulky and heavy. If you go for REST you can have such APIs as (similar interface you can have in WCF):
Category
Likewise for the Product
Is there any "generic" way that can be used in WCF service for this situation ?
Yes, you can use generics on the server, but to the client this will appear as a concrete type. See this post for an example.
Assuming you're talking purely about CRUD on "Reference" data (categories, products, and so on), you should have 1 service with lots of GetAllXXX methods or multiple services, eventually inheriting from a base one. It really doesn't matter, as if you have many DTOs to transfer, you will get lots of GetXXX methods.
Just be aware of those 2 points :
For example :
public class DataService<TIn>
{
protected List<TOut> GetAll<TOut>()
{
// handle generic loading and transformation here
}
}
public class CategoryService : DataService<Category>
{
public List<CategoryDTO> GetAllCategories()
{
return GetAll<CategoryDTO>();
}
}
or
public class DataService
{
protected List<TOut> GetAll<TIn, TOut>()
{
// handle generic loading and transformation here
}
public List<CategoryDTO> GetAllCategories()
{
return GetAll<Category, CategoryDTO>();
}
}
Then inside the generic method you can map from Category to CategoryDto using Automapper, for example.
Finally, for more user/business oriented services, you should have DTOs specific to the data you will present in each "View".
(1) yes, it is very much from an OOP perspective. But you tend to reach those issues with code generation from large databases :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With