3

I'm porting our old Active-Record based API over to a new structure to make unit testing easier etc. We are using the repository pattern for our data access and StructureMap for dependency injection.

I'm struggling a little now with how to structure everything. Using our 'Product' class as an example, we previously had our model, repository and factory parts all built into the product object, for example to load, edit and save a product we could something like (simplified):-

Dim p As New Product
If(p.Load(1))
   p.Name = "New Name"
   p.Save()
End If

And to get a collection of objects we had a Shared(static) method on the object which acted as a basic factory

Dim arrProds = Product.GetProducts()

After looking at a few examples, in our new structure we now have an IProductRepository, IProductService (which is the factory) and Product model class. So, something like this

Dim prodSvc = ObjectFactory.GetInstance(Of IProductService)
Dim prod = prodSvc.GetProduct(1) //Prod is an Instance of 'Product'
prod.Name = "New Name"
prodSvc.Save(prod)

However, the Product class has the ability to load related data, for example

Dim arrRelatedProds = prod.RelatedProducts

Which inside the Product class looks like this

Class Product
    Function RelatedProducts() As IList(Of Product)
        // prodSvc is an instance of IProductService which is passed into the 
        // Product class in the constructor (or via Dependency Injection)
        Return Me.prodSvc.GetRelatedProducts(Me.ProductID)
    End Function
End Class

I don't like this because it's difficult to test and because I don't like the fact that my 'Model' class (Product) calls the IProductService class directly.

Does anyone have any suggestions about a better way to structure all this?

Cheers

James

EDIT Probably the wrong time of year to ask this! Is there any clarification I can add to make this question answerable??

4

2 回答 2

1

I don't know if it's better or worse, but one way to structure it is to get rid of all smartness from your entity/data transfer object Product, and put everything including Create, Retreive, RetreiveAll, Save, GetRelatedProducts, etc. into IProductService. It would make your Product code simpler, and you don't have to worry which class does what.

于 2009-01-02T10:43:16.817 回答
1

When using the repository pattern instead of active record, don't reference to the repository in the domain object (product). It's not impossible, but you save yourself a lot of trouble when you don't. The best thing you can do is using an ORM that supports lazy loading. Personally I use NHibernate for that. Make your repository dependent on your domain objects, but the domain objects independent of the repository. The best thing to do is not to inject anything at all in your domain objects.

于 2009-01-02T11:31:21.243 回答