Can I get the classes generated using T4 Templates to inherit from the same class - t4

I'm writing a small console app to generate some scaffolding code using the TextTemplatingFilePreprocessor.
I have a number of .tt files that are used and they all use the same Model from which the values are derived for the individual classes. Following along this MSDN article I have created another partial class file for the class being created and added a constructor that allows me to pass in the Model.
So, for a class to be generated called ServiceEntity, I have a ServiceEntity.tt file and a 2nd file called something like ServiceEntityCode.cs which contains something like this...
partial class ServiceEntity
{
IServiceConfig _config;
public ServiceEntity(IServiceConfig config)
{
_config = config;
}
}
The thing is, I'm having to duplicate this code to create a constructor forr each class I'm generating.
I'd prefer to have something like...
class BaseTemplate
{
IServiceConfig _config;
public BaseTemplate(IServiceConfig config)
{
_config = config;
}
}
partial class ServiceEntity : BaseTemplate
{
public ServiceEntity() : base() {}
}
Can anyone give me a pointer to whether or not such a thing can be achieved and, if it can, where I might find details on how?
===EDIT===
Here's a sample template...
<## template debug="false" hostspecific="false" language="C#" #>
<## assembly name="System.Core" #>
<## import namespace="System.Linq" #>
<## import namespace="System.Text" #>
<## import namespace="System.Collections.Generic" #>
<## output extension=".cs" #>
using System.Runtime.Serialization;
namespace <#= _config.ServiceEntityNamespace #>
{
[DataContract()]
public class <#= _config.ServiceEntityName #>
{
[DataMember()]
public string Description { get; set; }
[DataMember()]
public int Id { get; set; }
[DataMember()]
public string Name { get; set; }
}
}
The .cs code generated under the .tt file includes this ...
public partial class ServiceEntity : ServiceEntityBase
{
//...
}
But ServiceEntityBase itself doesn't inherit from anything.

Is this what you are after?
namespace <#= _config.ServiceEntityNamespace #>
{
[DataContract()]
public class <#= _config.ServiceEntityName #> : BaseTemplate
{
public <#= _config.ServiceEntityName #>() : base() {}
[DataMember()]
public string Description { get; set; }
[DataMember()]
public int Id { get; set; }
[DataMember()]
public string Name { get; set; }
}
}

Related

Filtering on a GraphQL union type with HotChocolate

Imagine there is a GraphQL endpoint with which you can retrieve files and folders. Files have different properties than folders. I use HotChocolate (12.14.0) and Entity Framework Core (6.0.9) on .NET 6 and have defined my query and objects using a UnionType like this:
public class Query
{
[UseOffsetPaging(IncludeTotalCount = true)]
[UseProjection]
[UseFiltering]
[UseSorting]
public IQueryable<IFileOrFolder> GetFiles([Service] IFilesReadModel filesReadModel)
=> filesReadModel.GetFiles();
}
[UnionType("FileOrFolder")]
public interface IFileOrFolder
{
int Id { get; set; }
string Name { get; set; }
}
[Table("files")]
public abstract class FileOrFolder : IFileOrFolder
{
public int Id { get; set; }
public string Name { get; set; } = string.Empty;
}
public class File : FileOrFolder
{
public int Size { get; set; }
}
public class Folder : FileOrFolder
{
public ICollection<FileOrFolder> Files { get; set; } = new List<FileOrFolder>();
}
This generates the following schema (large parts omitted for brevity):
type Query {
...
filesAndFolders(
skip: Int
take: Int
where: IFileOrFolderFilterInput
order: [IFileOrFolderFilterInput!]
): FileOrFolderCollectionSegment
...
}
input IFileOrFolderFilterInput {
and: [IFileOrFolderFilterInput!]
or: [IFileOrFolderFilterInput!]
id: ComparableInt32OperationFilterInput
name: StringOperationFilterInput
}
As you can see, the generated input IFileOrFolderFilterInput enables filtering (where) on Id and Name (the properties that both File and Folder share and are implemented in the base class FileOrFolder), but not on the properties that are specific for File or Folder, like the Size property of File.
Is it possible to enable filtering on properties of a union type that are not shared between the individual classes?

AutoMapperMappingException: Missing type map configuration or unsupported mapping. [.NET Core 3.1]

I've build a WebAPI .NET Core 3.1 using AutoMapper v10.0 and AutoMapper Dependency Injection 8.0.1 and I'm encountering the following error
AutoMapperMappingException: Missing type map configuration or unsupported mapping.
Mapping types:
Role -> RoleResources
Entity.Models.Role -> Entity.Resources.RoleResources
lambda_method(Closure , Role , RoleResources , ResolutionContext )
AutoMapperMappingException: Error mapping types.
Mapping types:
ICollection`1 -> ICollection`1
System.Collections.Generic.ICollection`1[[Entity.Models.Role, Entity, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]] -> System.Collections.Generic.ICollection`1[[Entity.Resources.RoleResources, Entity, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]
lambda_method(Closure , ICollection<Role> , ICollection<RoleResources> , ResolutionContext )
I've tired to use .ReverseMap(), Mapthe ICollection directly in the profile with no luck.
Here is my classes
Role.cs
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace Entity.Models
{
[Table("Role")]
public class Role
{
[Key]
public Guid Id { get; set; } = Guid.NewGuid();
[Required]
public string Name { get; set; }
[Required]
public string Description { get; set; }
[Required]
public int RoleNumber { get; set; }
public ICollection<RolePrivilage> RolePrivilages { get; set; }
}
}
RoleResources.cs
using System;
using System.Collections.Generic;
using System.Text;
namespace Entity.Resources
{
public class RoleResources
{
public Guid Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public int RoleNumber { get; set; }
}
}
Startup.cs Configure method
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<WhiteLandsDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddControllers();
services.AddAutoMapper(typeof(Startup));
services.AddScoped<IRoleService, RoleService>();
services.AddScoped<IPrivilageService, PrivilageService>();
services.AddScoped<IRoleRepository, RoleRepository>();
services.AddScoped<IPrivilageRepository, PrivilageRepository>();
}
Mapping Profile
using AutoMapper;
using Entity.Models;
using Entity.Resources;
using System.Collections.Generic;
namespace Core.Mapping
{
public class MappingProfile : Profile
{
public MappingProfile()
{
//CreateMap<ICollection<Role>, ICollection<RoleResources>>();
CreateMap<Role, RoleResources>();
}
}
}
RoleController.cs
[HttpGet]
public async Task<ICollection<RoleResources>> Get()
{
var roles = await _roleService.List();
var resources = _mapper.Map<ICollection<Role>, ICollection<RoleResources>>(roles);
return resources;
}
can you please register your automapper in configuration service like below and give it a try ?
services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());

Why can't I use the Column data annotation with Entity Framework 5?

I want to use the Column data annotation as shown in the sample code below but the compiler (and also IntelliSense) do not seem to know that particular data annotation. I'm using EF 5 in Visual Studio 2010. I installed EF 5 using NuGet. The Required and MaxLength annotations are working.
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace Model
{
public class Destination
{
public int DestinationId { get; set; }
[Required]
public string Name { get; set; }
public string Country { get; set; }
[MaxLength(500)]
public string Description { get; set; }
[Column(TypeName="image")]
public byte[] Photo { get; set; }
public List<Lodging> Lodgings { get; set; }
}
}
What am I missing?
Column is in:
using System.ComponentModel.DataAnnotations.Schema;
the following code:
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
namespace ConsoleApplication2
{
public class MyContext : DbContext
{
public IDbSet<Entity> Entities { get; set; }
}
public class Entity
{
public int Id { get; set; }
[Column(TypeName = "image")]
public byte[] Photo { get; set; }
}
}
produces:

Oracle UDT Type Mismatch

We have a project which has two modules which uses same UDTs. We have generated UDT's shown in example code. When our project calls B's SP which should return UDT from B.DbObjects namespace, the returned type is A.DbObjects namespace. This occurs because Oracle Data Access gets type name from OracleCustomTypeMappingAttribute and creates instance with that value. Since the namespaces are different, we cannot bind data to our return type. Is there a solution for this?
Code:
Module A - Output A.dll
namespace A.DbObjects
{
[OracleCustomTypeMapping("SCHEMA.UDTNAME")]
public partial class UDTNAME : OracleCustomType
{
[OracleObjectMappingAttribute("X")]
public string X { get; set; }
[OracleObjectMappingAttribute("Y")]
public decimal Y { get; set; }
[OracleObjectMappingAttribute("Z")]
public decimal Z { get; set; }
}
}
Module B - Output B.dll
namespace B.DbObjects
{
[OracleCustomTypeMapping("SCHEMA.UDTNAME")]
public partial class UDTNAME : OracleCustomType
{
[OracleObjectMappingAttribute("X")]
public string X { get; set; }
[OracleObjectMappingAttribute("Y")]
public decimal Y { get; set; }
[OracleObjectMappingAttribute("Z")]
public decimal Z { get; set; }
}
}

MVC 3, DI, And Best Practices With Views

Consider the two views. Which is preferred and what is a situation where you would use style 1 and not style 2 and vice versa?
Style 1 : View Injection
using System.Web.Mvc;
using Ninject;
namespace Views.Models.ViewClasses {
public abstract class CalculatorView : WebViewPage {
[Inject]
public ICalculator Calulator { get; set; }
}
}
And the view:
#inherits Views.Models.ViewClasses.CalculatorView
#{
ViewBag.Title = "Calculate";
}
<h4>Calculate</h4>
The calculation result for #ViewBag.X and #ViewBag.Y is #Calulator.Sum(ViewBag.X, ViewBag.Y)
Style 2: Using a Model
public class CalculatorModel {
// a constructor in here somewhere
public int X { get; set; }
public int Y { get; set; }
public int SumXY { get; set; }
}
The Controller:
public class CalculatorController : Controller {
private readonly ICalculator _calculator;
[Inject]
public CalculatorController (ICalculator calculator) {
_calculator = calculator;
}
public ActionResult Calculate(int x, int y)
{
return View(new CalculatorModel(x, y, _calculator.Sum(x, y))
}
...
The view:
#model CalculatorModel
#{
ViewBag.Title = "Calculate";
}
<h4>Calculate</h4>
The calculation result for #Model.X and #Model.Y is Model.SumXY
All I can really think of is:
If the calculator or whatever needs to be used a lot in the view, then view injection makes more sense as otherwise the model would have loads and loads of data otherwise models should be preferred?

Resources