currently the code which i have is generating the properties like
private int integerProperty
{
get
{
return integerField;
}
set
{
integerField = value;
}
}
I wanted the properties to be simple like...
private int integerProperty
{
get;
set;
}
The code i have with me is
CodeMemberProperty property1 = new CodeMemberProperty();
property1.GetStatements.Add(new CodeMethodReturnStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "integerField")));
property1.SetStatements.Add(new CodeAssignStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "integerField"),new CodePropertySetValueReferenceExpression()));
type1.Members.Add(property1);
Anyone please help. Thanks in advance.
As Botz3000 mentioned, it's officially not possible. However, with the following hack you can implement it:
var field = new CodeMemberField
{
Attributes = MemberAttributes.Public | MemberAttributes.Final,
Name = "MyProperty",
Type = new CodeTypeReference(typeof(MyType)),
};
field.Name += " { get; set; }";
By appending { get; set; } to the field name, it will generate a property in the actual source code.
This is an old question, but is worth noting that the answer by "#Serguei Fedorov" is no longer applies (it's valid only for c# 1.0 to c# 2.0)
The solution of replacing "};" with "}" should be avoid, because "};" is used for the syntax of Object and Collection Initializers starting from C# 3.0.
Review Object and Collection Initializers.
Example:
var pet = new { Age = 10, Name = "Fluffy" }; //it's ended by "};"
Alternative solution
You can use the new .NET Compiler Platform ("Roslyn") which support C# 1.0 to c#6.0.
The samples include ConvertToAutoProperty - A code refactoring to change a simple property with a trivial getter and setter into an auto property.
If you interested by CodeDom, there's a new CodeDOM Providers for .NET Compiler Platform (“Roslyn”) that can be installed from nuget
No, it's not possible. Automatic properties are a language specific feature, so you won't find any way to generate those.
Related
I'm trying to interop with a C# library in some F# code. Consider the following C# as though it were the library I'm working with (or skip below to see the actual library I'm working with first):
public class Options
{
public Options(string name)
{
Name = name;
}
public string Name { get; }
public string SomeProperty { get; set; }
}
public class ServiceBuilder
{
public ServiceBuilder ApplyOptions(Options options)
{
//Apply Options in some way
return this;
}
public TheService Build()
{
return new TheService();
}
}
public class TheService
{
}
I'm then trying to create the service but keeping it fluent I have the following F# code:
//Valid Approach but not inlined :(
let options = Options("Test")
options.SomeProperty <- "SomeValue"
let theService =
ServiceBuilder()
.ApplyOptions(options)
.Build();
//Invalid Approach because SomeProperty is not virtual
let theService2 =
ServiceBuilder()
.ApplyOptions({
new Options("Test2") with
member _.SomeProperty = "SomeValue2"
})
.Build()
Is there some way for me to initialize the way I want to inline in F# where I try to create "theService2"? In C# I'd just use Object Intializers. F# Object Expressions are out because I don't have control of the class to make the property virtual.
For additional context in what my C# above is mocking, I'm specifically trying to create a Serilog Logger using the Serilog.Sinks.ElasticSearch nuget package and do roughly the code below in F# (again, inlined if possible):
var loggerConfig = new LoggerConfiguration()
.WriteTo.Elasticsearch(new ElasticsearchSinkOptions(new Uri("http://localhost:9200") ){
AutoRegisterTemplate = true,
AutoRegisterTemplateVersion = AutoRegisterTemplateVersion.ESv6
});
In F# you can also assign values to properties at initialization, so to create your Options instance in a single expression you can do the following:
Options("Test", SomeProperty="SomeValue")
For direct translation from C# - property initializers are the way to go, as suggested in #rob.earwaker's answer.
However, note also that in F# everything is an expression. There are no "statements" like in C#, every piece of code has a result of some kind. And this also goes for "composite", so to say, pieces of code, such as let blocks. This means, even if you don't feel like using property initializers, you can still do the initialization inline:
let service =
ServiceBuilder()
.ApplyOptions(
let o = Options("Test")
o.SomeProperty <- "SomeValue"
o
)
.Build()
Or using let .. in and a semicolon to put everything on the same line:
let service =
ServiceBuilder()
.WithOptions(let o = Options("Test") in o.SomeProperty <- "SomeValue"; o)
.Build()
Unlike C#, this approach also works for factoring out initializations into reusable pieces:
let service =
ServiceBuilder()
.WithOptions(let o = Options("bar") in mutateSomeOptions(o); mutateOtherOptions(o); o)
.Build()
On occasion, I like to log a module's version number. How do I get a module's version number within code (programmatically)?
In the same way you request IOrchardServices in your controller's constructor, you can request IExtensionManager. Then, using the GetExtension method with the name of the module (as indicated in module.txt id), it returns an ExtensionDescriptor that exposes the Version property, among other useful properties.
You can see an example of using IExtensionManager in the RecipeHarvester source code.
If you need to access a module from anywhere in the code, you would need to initialize an ExtensionManager first. To do that, you will need the current workContext. This is the way I did that.
public class Extensioner
{
public IExtensionManager _manager { get; set; }
public Extensioner()
{
var httpContextAccessor = System.Web.Http.GlobalConfiguration.Configuration.DependencyResolver.GetService(
typeof(IHttpContextAccessor)) as IHttpContextAccessor;
var workContext = WorkContextExtensions.GetWorkContext(httpContextAccessor.Current().Request.RequestContext);
_manager = workContext.Resolve<IExtensionManager>();
}
public string getModuleVersion(string moduleName)
{
var _ver = "unknown";
if (_manager != null)
{
_ver = _manager.GetExtension(moduleName).Version;
}
return _ver;
}
}
The page which showed me the way:
https://disqus.com/home/discussion/skywalkersoftwaredevelopment/orchard_webapi_global_actionfilters_and_dependency_injection/
And some theory:
https://orcharddojo.net/orchard-resources/Library/Wiki/WorkContext
Helllo..... I am quite new in Microsoft Enterprise Library Validation Framework. My question is that I want same validation condition in two different RuleSet.
Is it possible to put two rule set with in the same Validator like below
/// <summary>
///
/// </summary>
[StringLengthValidator(1,25,Ruleset="DetailRuleSet",Ruleset="MainRuleSet",Tag="First Name")]
public string FirstName
{
get { return firstName; }
set { firstName = value; }
}
or I have mentioned it by writing the same in two time with different ruleset name like below
/// <summary>
///
/// </summary>
[StringLengthValidator(1,25,Ruleset="DetailRuleSet",Tag="First Name")]
[StringLengthValidator(1, 25, Ruleset = "MainRuleSet", Tag = "First Name")]
public string FirstName
{
get { return firstName; }
set { firstName = value; }
}
Any help would be appreciated!!
First a disclaimer: I haven't worked so much on the Enterprise Library Application Validation Block, however, having been a programmer for over a decade and a half, and having used Validation models from ASP.NET to MVC Data Annotations, I can tell you that the API for validation in Enterprise Library is pretty similar. It took me about 20 minutes to download the Enterprise Library source code and look up the answer to this question. So, here's my answer.
Yes, you can apply more than one validation attribute to a given model property, each validation attribute specifying a different rule set.
However, in such a case, you will have to explicitly invoke the validator on the model type for that particular rule set.
If you do not do that, the Enterprise Library will execute the validator for the default rule-set.
In the context of your example, you can say:
StringLengthValidator(1,25,Ruleset="DetailRuleSet",Tag="First Name")]
[StringLengthValidator(1, 25, Ruleset = "MainRuleSet", Tag = "First Name")]
public string FirstName
{
get { return firstName; }
set { firstName = value; }
}
However, in this case, you have to specifically invoke one of the rule-sets for validation, like so:
var yourModelObjectValidator =
yourValidatorFactory.CreateValidator<YourModelClass>("yourRuleSetName");
var yourModelObject =
new YourModelClass { Foo = "foo", Bar = "bar", Gar = 2 };
var results =
yourModelObjectValidator.Validate(yourModelObject);
if (!results.IsValid)
{
foreach(var result in results)
{
/* run the state machine, do whatever, print */
}
}
If you do not specify the rule set name like we did above, the Enterprise Library will execute your validations in the context of a default rule set which has no name, and hence none of the two rules you specified above using the validation attributes will get executed.
UPDATE
Based on your comment, I see what your real question is.
Your question then really is: Can I specify more than a single rule-set in a single validation attribute declaration?
The answer is as simple as the question: No. Because the property RuleSet is declared simply as string and not as IEnumerable<string> in the BaseValidationAttribute class, the mother of all ValidatorAttribute classes in the EntLib source code.
i stumbled to the next problem... I have database context:
// For support unit testing...
public interface IDbContext : IDisposable
{
IQueryable<Hardware> Hardwares { get; }
IQueryable<ProviderHardware> ProviderHardwares { get; }
}
// Real DbContext (EF 4.0, Code First)
public class PrimaryDbContext : DbContext, IDbContext
{
public DbSet<Hardware> Hardwares { get; set; }
public DbSet<ProviderHardware> ProviderHardwares { get; set; }
IQueryable<Hardware> IDbContext.Hardwares
{ get { return Hardwares; } }
IQueryable<ProviderHardware> IDbContext.ProviderHardwares
{ get { return ProviderHardwares; } }
...
}
And i try get all hardwares, which doesnt exists in ProviderHardwares table:
var hardwaresRemoved = db.Hardwares.Where(i => (i.IsAvailable == true) &&
(db.ProviderHardwares.Count(j => j.Article == i.Article) == 0)).ToList();
If i use PrimaryDbContext strictly such as "PrimaryDbContext db = new PrimaryDbContext();" all work fine. But if i use it implicitly "IDbContext db = new PrimaryDbContext();" that i get an exception:
Unable to create a constant value of type
'ConfiguratorMvcApplication.DomainModels.ProviderHardware'. Only
primitive types ('such as Int32, String, and Guid') are supported in
this context.
Summarize, i can't replace a DbSet on an IQueryable. And how i can use unit testing in this case? I hope someone have resolved this problem yet...
Thank in advance very much!
I ended up having two properties for each DbSet: one of type IQueryable, and one of type DbSet. The IQueryable property is defined in the interface, and it relays the calls to the concrete implementation (property of type DbSet), as follows:
// Exists in the interface
public IQueryable<AccountContact> AccountContacts
{
get
{
return DbAccountContacts;
}
set
{
DbAccountContacts = (DbSet<AccountContact>)value;
}
}
// Exists only in the implementation
public DbSet<AccountContact> DbAccountContacts { get; set; }
Having this setup, I was able to get mocking to work correctly and could unit test the code.
This is definitely too late for the OP, but maybe this helps someone who is struggling with the same question, as I did.
I suggest you better keep DbSets and do INTEGRATION TESTING including the database.
Because, although passing a unit test with a mock of a DB could be somewhat usefull, you are going to be better off testing with real database (but it's not unit testing).
On the ClassInitialize erase the database and/or create the initial data for testing.
If you create an App.config file with a connection string you can have a separate test database, and if you are using EF Code First, you get it for free.
Best regards.
I have been building a new .NET solution with Castle performing my DI.
Its now at the stage where i would like to control the order in which my installers run. I have built individual classes which implement IWindsorInstaller to handle my core types — eg IRepository, IMapper and IService to name a few.
I see that its suggested i implement my own InstallerFactory (guessing i just override Select) in this class.
Then use this new factory in my call to:
FromAssembly.InDirectory(new AssemblyFilter("bin location"));
My question — when overriding the save method — what is the best way to force the order of my installers.
I know its already solved but I couldn't find any example on how to actually implement the InstallerFactory so here's a solution if anyone is googling for it.
How to use:
[InstallerPriority(0)]
public class ImportantInstallerToRunFirst : IWindsorInstaller
{
public void Install(IWindsorContainer container, Castle.MicroKernel.SubSystems.Configuration.IConfigurationStore store)
{
// do registrations
}
}
Just add the InstallerPriority attribute with a priority to your "install-order-sensitive" classes. Installers will be sorted by ascending. Installers without priority will default to 100.
How to implement:
public class WindsorBootstrap : InstallerFactory
{
public override IEnumerable<Type> Select(IEnumerable<Type> installerTypes)
{
var retval = installerTypes.OrderBy(x => this.GetPriority(x));
return retval;
}
private int GetPriority(Type type)
{
var attribute = type.GetCustomAttributes(typeof(InstallerPriorityAttribute), false).FirstOrDefault() as InstallerPriorityAttribute;
return attribute != null ? attribute.Priority : InstallerPriorityAttribute.DefaultPriority;
}
}
[AttributeUsage(AttributeTargets.Class)]
public sealed class InstallerPriorityAttribute : Attribute
{
public const int DefaultPriority = 100;
public int Priority { get; private set; }
public InstallerPriorityAttribute(int priority)
{
this.Priority = priority;
}
}
When starting application, global.asax etc:
container.Install(FromAssembly.This(new WindsorBootstrap()));
You can call your installers in the order they need to be instantiated in Global.asax.cs or e.g. in a Bootstrapper class, which is called from Global.asax.cs.
IWindsorContainer container = new WindsorContainer()
.Install(
new LoggerInstaller() // No dependencies
, new PersistenceInstaller() // --""--
, new RepositoriesInstaller() // Depends on Persistence
, new ServicesInstaller() // Depends on Repositories
, new ControllersInstaller() // Depends on Services
);
They are instantiated in this order, and you can add a breakpoint after and check the container for "Potentially misconfigured components".
If there are any, check their Status->details, if not, it's the correct order.
This solution is quick and easy, the documentation mentions using a InstallerFactory Class for tighter control over your installers so if you have a ton of installers the other solution may fit better. (Using code as convention should not require tons of installers?)
http://docs.castleproject.org/Windsor.Installers.ashx#codeInstallerFactorycode_class_4
In the end i had to use InstallerFactory and implement the ordering rules as suggested previously by returning the IEnumerable<Type> with my specific order