views:

1786

answers:

5

Ok,

So, I have a class library with all my database logic. My DAL/BLL.

I have a few web projects which will use the same database and classes, so I thought it was a good idea to abstract the Data Layer into its own project.

However, when it comes to adding functionality to classes for certain projects I want to to add method to certain classes.

For Example. My Data Layer has Product and SomeItem Objects:

// Data Access Layer project

namespace DAL {
  public class Product { 
     //implementation here 
  }

  public class SomeItem {
     //implementation here 
  }
}

In one Project I want to add an interface that is used by different Content Items, so I have a class called:

// This is in Web Project
namespace DAL {
  public partial class Product : ICustomBehaviour {

    #region ICustomBehaviour Implementation
       TheSharedMethod();
    #endregion
  }
}

The Question is:

Is this a good idea to write a partial class in a separate project (creating a dependency) using the SAME namespace?

If it's a bad idea, how can I get this type of functionality to work?

It doesn't seem to want to merge them at compile time, so I'm not sure what I'm doing wrong.

+10  A: 

You can't write a partial class across projects. A partial class is a compile-time-only piece of syntactic sugar - the whole type ends up in a single assembly, i.e. one project.

(Your original DAL file would have to declare the class to be partial as well, by the way.)

Jon Skeet
Do you never sleep!? :)
Kent Boogaart
So, then can i add "Interface" functionality to a class in another project?
Atømix
@Kent: Not at 8 o'clock in the evening, no :)
Jon Skeet
@Atomiton: You can't change the existing class from a different project, no. You *could* derive from the existing class and also implement the interface. That has some downsides though - most notably that you have to make sure that you always create an instance of your new type not the base one.
Jon Skeet
@Kent Boogart: I'm with you. It's rare that I come across an interesting question that Jon Skeet hasn't commented on.
Atømix
@Jon: Yeah. I went down the route and ran into that limitation. I may end up doing that, though.
Atømix
+1  A: 

Partial classes have to exist in the same assembly. Otherwise, how would the compiler decide where to merge the partial classes to?

Kent Boogaart
Actually, I thought that once I put them in the same namespace they would compile to the same assembly (in essence creating a unique assembly for each project)
Atømix
A: 

I agree with Jon Skeet's answer.

I don't think it would be a good choice to approach an issue like this anyway. There are good design patterns out there already that demonstrate the best way to split your tiers/layers of code, and this is just a little syntactic sugar so that Microsoft could make the WinForms/WebForms designer files separate and prevent people from breaking them.

Neil Barnwell
Got any suggestions as a good design pattern to follow? My DAL is built using LINQ, so that's why I have less control over the Actual Data Classes.
Atømix
A: 

While I agree with you Neil when it comes to pre-linq development, I also wish I could be able to do this in order to split up bussiness logic from partial classes generated by Linq2SQL designer. For example:

Northind.DAL (prj)
-NorthindDataContext (EntityNamespace set to "Northwind.BLL")
--Product() (Entity, partial class auto-generated)
--Category() (Entity, partial class auto-generated)
--Supplier() (Entity, partial class auto-generated)

Northind.BLL (prj)
-Product() : IMyCustomEnityInterface, BaseEntity (override OnValidate(), etc)
-Category() : IMyCustomEnityInterface, BaseEntity (override OnValidate(), etc)
-Supplier() : IMyCustomEnityInterface, BaseEntity (override OnValidate(), etc)

Unfortunately, we can not do this... actually I'd love to know what the recommended way of splitting up layers/tiers when using LINQ.

A: 

I can't answer your question about the best way to organize your layers, but I can try to answer your question about how best to emulate partial classes.

Here are a few thoughts:

  • The first thing that springs to mind is inheritance. It's not necessarily the best solution always, but you may not have a choice since you may need to be able to have your objects be able to be treated like the base class.
  • Composition is also a good choice (that is, wrapping the class in another class). This gives you a little bit nicer decoupling from your DAL, but can be tedious to implement.
  • If you really just need to add a method or two onto an existing class, you might also consider using an extension method, but these can quickly create spaghetti code if you use them too much.
Jason Baker