Search code examples
c#modelspetapoco

How would I use a seperate Models only project with PetaPoco?


I currently have the following in one solution:

  1. Core Project (data access, biz logic, petapoco for data access, the plumbing, etc)
  2. Models Project (just models and petapoco decorations for just attributes)
  3. Web Project (MVC project for presentation

I want to have my Models and Core seperate, but I can't have PetaPoco.cs in both places. How would I seperate it and still be able to decorate the POCOs in my Models project with PetaPoco attributes?

I don't want the Models project to have a dependency on the Core project.

I did create this seperate class to be only in the Models project so I could decorate the POCOs, but the attributes are not being picked up properly by the Core PetaPoco project. It relies on PocoData too much.

Suggestions?

// Poco's marked [Explicit] require all column properties to be marked
[AttributeUsage(AttributeTargets.Class)]
public class ExplicitColumnsAttribute : Attribute
{
}
// For non-explicit pocos, causes a property to be ignored
[AttributeUsage(AttributeTargets.Property)]
public class IgnoreAttribute : Attribute
{
}

// For explicit pocos, marks property as a column and optionally supplies column name
[AttributeUsage(AttributeTargets.Property)]
public class ColumnAttribute : Attribute
{
    public ColumnAttribute() { }
    public ColumnAttribute(string name) { Name = name; }
    public string Name { get; set; }
}

// For explicit pocos, marks property as a result column and optionally supplies column name
[AttributeUsage(AttributeTargets.Property)]
public class ResultColumnAttribute : ColumnAttribute
{
    public ResultColumnAttribute() { }
    public ResultColumnAttribute(string name) : base(name) { }
}

// Specify the table name of a poco
[AttributeUsage(AttributeTargets.Class)]
public class TableNameAttribute : Attribute
{
    public TableNameAttribute(string tableName)
    {
        Value = tableName;
    }
    public string Value { get; private set; }
}

// Specific the primary key of a poco class (and optional sequence name for Oracle)
[AttributeUsage(AttributeTargets.Class)]
public class PrimaryKeyAttribute : Attribute
{
    public PrimaryKeyAttribute(string primaryKey)
    {
        Value = primaryKey;
        autoIncrement = true;
    }

    public string Value { get; private set; }
    public string sequenceName { get; set; }
    public bool autoIncrement { get; set; }
}

[AttributeUsage(AttributeTargets.Property)]
public class AutoJoinAttribute : Attribute
{
    public AutoJoinAttribute() { }
}

Solution

  • I think one obvious solution, though, I'm not sure it's that much better, is to move PetaPoco to its own project and then reference that in both your Core and Models projects. Your models still have an external dependency, though, just not the whole Core assembly.

    One other alternative would be to have your decorated models in your Core project for internal use, and then have a set of undecorated classes in your Models assembly. You could use an auto-mapping component to map between the two easily. So basically you would use PetaPoco to fetch data into your internal model, and then map that over to your 'external' model which is just bare classes with no dependencies.

    Of course, that sounds like a lot of extra work. I guess it all hinges on how critical it is that your Model assembly have no other dependencies.