Question

I'm working with self tracking entities on a n-tier application. So I have a WCF service which provides the client access to the data layer and I find myself implementing a lot of the "same" functions corresponding with Getting some entities from my model, for example GetOrders, and after changing them in the client, a Save(Order order) or Save(TrackableCollection<Orders> orders) operation to persist the changes.

I'm wondering if there exists a T4 template that could build the basic interface, with Get/Save for single and collections of each entity and the corresponding service implementation from my model?

I'm aware that I could write my own T4 Template to generate this service, and I will probably do just that if I have to, but first I thought I'd ask the community if this effort exists already somewhere on the internet, is planned, is desired by others and/or is a totally stupid idea.

I did find this WCF Data Services Generator example, which is kind of on the right track.

Maybe something more suited to STEs using WCF in an n-tier solution is out there?

Was it helpful?

Solution

There are out there (more), but you'll always need to customise. I've customised the simple templates found online, and in essence what it does is create the operation contracts, and web methods for visibility to win32 clients. Below is an excerpt:

// I obtain anykeys by iterating through the entity keys:
_anyKeys = string.Format("{0}{1} item.{2} == {3}_dto.{2}", _anyKeys, _and, key.ToString(), _double);
    // loop through all the entities:
    foreach (EntityType entity in Item1Collection.GetItems<EntityType>().OrderBy(e => e.Name))
    {

    /// <summary>
    /// <#=code.Escape(entity)#> Operation contracts - <#=code.Escape(entityName)#> 
    /// </summary>  
    [WebMethod]
    public bool Save<#=code.Escape(entity)#>(Dto<#=code.Escape(entity)#> _dto, int racID, string profile)
    {
        try
        {
            // Load the db
            using (<#=ContextName#> db = new <#=ContextName#>(EFUtils.GetEFConnectionString(profile, modelName)))
            {
                // Check if item exists         
                var exists = db.<#=code.Escape(entityName)#>.Any(item=> <#=code.Escape(_anyKeys)#>);
                // convert to entity
                var _entity = _dto.ToEntity();
                if(exists)
                {
                  // Attach the entity to the db
                  db.<#=code.Escape(entityName)#>.Attach(_entity);
                  // Change tracking
                  ChangeTracking<<#=code.Escape(entity)#>>(_dto.ModifiedProperties, db, _entity);
                }
                else
                {
                  // New entity
                  db.<#=code.Escape(entityName)#>.Add(_entity);
                }
                // Save changes
                return db.SaveChanges() > 0;
            }
        }
        catch(Exception ex)
        {               
            Global.LogMessageToFile(ex, string.Format("{0} - profile {1}, Save<#=code.Escape(entity)#>", racID, profile));
        }
        finally
        {       
        }
        return false;
    }


// Then the interfaces
#>
#region <#=code.Escape(entity)#>
    /// <summary>
    /// <#=code.Escape(entity)#> Operation contracts - <#=code.Escape(entity.Name)#> 
    /// </summary>  
    [OperationContract]
    bool Save<#=code.Escape(entity)#>(Dto<#=code.Escape(entity)#> _dto, int racID, string profile);
    [OperationContract]
    bool Delete<#=code.Escape(entity)#>(<#=code.Escape(_keys)#>, int racID, string profile);
    [OperationContract]
    Dto<#=code.Escape(entity)#> Get<#=code.Escape(entity)#>(<#=code.Escape(_keys)#>, string  filterXml, int racID, string profile);
    [OperationContract]
    List<Dto<#=code.Escape(entity)#>> List<#=code.Escape(entityName)#>(string  filterXml, int racID, string profile);   
#endregion
<#+ 
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top