I find the lambda expressions needed for importing of properties somewhat confusing and I am trying to also understand how to use MEF conventions for importing and exporting so maybe I am trying to take on too much at once.
I am exporting ResourceDictionary with a contract name which I imported previously like this:
[ImportMany("ApplicationResources", typeof(ResourceDictionary))]
public IEnumerable<ResourceDictionary> Views { get; set; }
Which works well and is fine, however I am now trying to import this via a RegistrationBuilder but not fully understanding how to do this.
This exports them I believe (but I have to be honest I don't fully understand the syntax):
var registration = new RegistrationBuilder();
registration.ForTypesDerivedFrom<ResourceDictionary>()
.Export<ResourceDictionary>(x => x.AsContractName("ApplicationResources"));
I have a property in my App that I wish to populate
So tried this (carried out within the App itself)
registration.ForType<App>()
.ImportProperty<ResourceDictionary>(x => x.Views);
But this isn't working and I am guessing I need to set contract name somehow? Can anyone tell me what the syntax for this is? Maybe if I can see the correc syntax I can better understand how it works... I hope!
Typically it turns out that I found the solution after posting the question. I don't tend to answer my own questions but as it had me stuch for a while and in case it helps anyone else this is what works:
registration.ForType<App>()
.ImportProperty<ResourceDictionary>(x => x.Views, ib => ib.AsContractName("ApplicationResources"));
However this only works if I use SafisfyImportsOnce rather than ComposeParts which I am slightly confused about
Related
I know templates are common within c/c++ however I am currently trying to translate an old VB code our company uses up to a c# equivalent which brings me to my problem....
VB is an type unsafe language so we come across things like
Public Elements As New Collection
so given the line above I need to translate that to a List.. Given that a Collection can be anything from a List to a map I need to template this as efficiently as possible. I was thinking of for first draft ignoring the map option entirely and just making it a List however from my understanding Templates don't truly exist within C#... The below code is what I came up with so far and while it compiles (I have not gotten to a testing point in the rest of the code yet) I don't know if it would actually work...
Public List<ValueType> Elements = new List<ValueType>();
can anyone offer input on if this would work as a generic list where type is determined at input or if I need to change this so the constructor would look more like
Public List<ValueType> Elements = new List<typeof(foo)>();
if the above is confusing I am sorry it is for me as well, and I will try and clarify as questions come in.
this question is no longer relevant, I was able to go into the source of the calling code and determine what variable types that the lists need to support.
I'm attempting to use client-side validation in an admin page in Orchard. I've been successful at making it work using the techniques discussed in this question, but after doing some digging in the Orchard source and online, it seems to me that commenting out these lines
// Register localized data annotations
ModelValidatorProviders.Providers.Clear();
ModelValidatorProviders.Providers.Add(new LocalizedModelValidatorProvider());
is subverting some built-in Orchard functionality which allows for localized error strings. At this point, either having these lines in our out of OrchardStarter.cs is the only difference between validation working and not working for me.
What I'm hoping for is some guidance on this, maybe from the Orchard team. If these lines have to be out in order for validation to work, why are they there in the first place? If they are there for a good reason, what am I (and others) doing wrong in our attempts to get client-side validation working? I'm happy to post code samples if needs be, although it's a pretty standard ViewModel with data annotations. Thanks.
The lines are there to replace the DataAnnotationsModelValidatorProvider (DAMVP) with Orchard's own implementation, which allows localizing the validation messages the Orchard way. The way it does this is by replacing e.g. [Required] with [LocalizedRequired] before passing control on to the DAMVP. Note that DAMVP does get to do its job - but only after Orchard has "messed" with the attributes.
The problem is that DAMVP uses the type of the Attribute to apply client validation attributes. And now it won't find e.g. RequiredAttribute, because it's been replaced by LocalizedRequiredAttribute. So it won't know what - if any - client validation attributes it should add.
So, out-commenting the lines will make you lose Orchard's localization. Leaving them in will make you lose client validation.
One workaround that might work (haven't looked enough through Orchard's code, and haven't the means to test at the moment) would be to make DAMVP aware of Orchard's Localized attributes and what to do with them.
DAMVP has a static RegisterAdapter() method for the purpose of adding new client rules for attributes. It takes the type of the attribute and the type of the Client-side adapter (the class that takes care of adding client attributes) to use.
So, something like the following might work:
In OrchardStarter.cs:
// Leave the LocalizedModelValidatorProvider lines uncommented/intact
// These are the four attributes Orchard replaces. Register the standard
// client adapters for them:
DataAnnotationsModelValidatorProvider.RegisterAdapter(
typeof(LocalizedRegularExpressionAttribute),
typeof(RegularExpressionAttributeAdapter)
);
DataAnnotationsModelValidatorProvider.RegisterAdapter(
typeof(LocalizedRequiredAttribute),
typeof(RequiredAttributeAdapter)
);
DataAnnotationsModelValidatorProvider.RegisterAdapter(
typeof(LocalizedRangeAttribute),
typeof(RangeAttributeAdapter)
);
DataAnnotationsModelValidatorProvider.RegisterAdapter(
typeof(LocalizedStringLengthAttribute),
typeof(StringLengthAttributeAdapter)
);
As for the official word, it would seem this hasn't worked since localized validation was introduced in 1.3, and the impact is considered low: http://orchard.codeplex.com/workitem/18269
So, at the moment, it appears the official answer to the question title is, "it shouldn't".
Task:
Rip through all the code in the entire solution and wrap all webservice method-calls in another ws method-call that accepts a GUID (it's a login scenario)
Background :
Hundreds of web services, add token security. As explained to me when I was assigned to the task, we do it this way because if, in the future , some changes to security etc have to be made we can just do it in the WrappermethodClass in stead of having to change hundreds of web services
Tried and failed :
Find all references : too much data , returned more than 1000 hits , most of which are useless as they're only object references.
Rename WS so all references beak, build the project I'm working on and fix as I go : works well with the services not integral to the functionality but as soon as I do it with an important one it's like I shot the Solution through the brain, everything's f****d and and VS just gives up trying.
Current Solution :Open all relevant docs, Find ,select All Open Docs, skip through.
Question : How do I do this as efficiently as possible?
Code (before) :
wsGeneric wsGen = new wsGeneric();
wsGen.DoSomething();
Code (after) :
WrapperMethodClass.DoCheck takes params of (Action, GUID),
wsGeneric wsGen = new wGeneric();
wrapperMethodClass.DoCheck((g) =>
{ wsGen.UserInfo.token = g.ToString();
wsGen.DoSomething();
},Shell.token.Value);
Don´t you have some sort of interface or class where you changed the method signature already?
If you changed your webservice and your Code still compiles i´d say you did something wrong or i don´t understand the question.
Update:
I still don´t get it.
I think you have these options:
Change the method signature (all calls should be broken now, fix all the errors vs gives you and you should be done)
Find all references (of the method, not your webservice-class) and change the calls
If above isn´t possible use "Find in Files" and search for the method-name
If all your webservices inherit from an interface or base class you can refactor this method to add a parameter, all inheriting classes will also have the parameter.
If you pass a login object to each webservice, you can add a GUID element to this object and you're done.
It would be a lot easier if you showed us some code, some function interfaces that you have to change and how.
A better solution may be to just use PostSharp to add the checks to your services. This will solve your business problem (you only need to update your aspects) and is much less error prone then your current approach since you don't have to wory about some new developer forgetting to make the call to DoCheck.
Not having to find all references is a side benefit.
I'm considering using PostSharp for entity-to-DTO and DTO-to-entity mapper. To do that task manualy for about a 100 entities would be a maintenence nightmare. I've looked at AutoMapper on codeplex, but i think the overhead might be a serious problem in my case, besides i feel that PostSharp could give me some extra control over the mapping convention. If anyone can share any experiences with this king of problems, that would be great.
The direction i'm think in is something like this (please somebody tell me if this is not possible):
The aspect that i am planing to stick to a class would fill the next two methods with content:
EntityType EntityToDTO(DTOType DTO) {}
DTOType DTOToEntity(EntityType Entity) {}
The first method would return entity based on DTO, the second one would do the oposite. Inside the aspect i'm planing to loop through each property, create new target and asign the value of a property to the counterpart from target object. Is this possible to do at compiletime witout any runtime overhead?
If your DTOs field names match your entity field names, then I'd use Duck Typing
http://www.deftflux.net/blog/page/Duck-Typing-Project.aspx
http://haacked.com/archive/2007/08/19/why-duck-typing-matters-to-c-developers.aspx
Your code would work like this
UserDTO user = DuckTyping.Cast<UserDTO>(userEntity);
Basically, the duck typing library will be mapping over the fields by matching the names. They use dynamically generated IL to archive this.
If that has the potential of being too slow, I'd probably try to get CodeSmith to generate the methods for me.
If it helps, there is a project called PostSharp4ET that basically implements support for POCO objects to Entity Framework 1. See http://www.codeplex.com/efcontrib.
Note that PostSharp is not very good at generating new code. It is good at mixing new code with existing one. If you need to generate code, I would recommend writing a C# code generator based on reflection, and compile the resulting code. Or use a tool like CodeSmith, as mentioned previously.
Basically what I'm hoping for is something that would work like how the Obsolete attribute works with Intellisense and strikes the method text when typing out the name. What I'm looking for is an attribute that blocks the method from being seen with the assembly it's defined. Kind of like an reverse internal. Using 3.5 by the by.
Yeah sounds odd but if you need the reason why, here it is:
My current solution for lazy loading in entity framework involves having the generated many to one or one to one properties be internal and have a facade? property that is public and basically loads the internal property's value:
public ChatRoom ParentRoom
{
get
{
if(!ParentRoomInnerReference.IsLoaded)
{
ParentRoomInnerReference.Load();
}
return ParentRoomInner;
}
set
{
ParentRoomInner = value;
}
}
Problem with this is if someone tries to use the ParentRoom property in a query:
context.ChatItem.Where(item => item.ParentRoom.Id = someId)
This will blow up since it doesn't know what to do with the facade property when evaluating the expression. This isn't a huge problem since the ParentRoomInner property can be used and queries are only in the entity assembly. (IE no selects and such in the UI assembly) The only situation comes in the entity assembly since it can see both properties and it's possible that someone might forget and use the above query and blow up at runtime.
So it would be nice if there were an attribute or some way to stop the entity assembly from seeing (ie blocked by intellisense) the outward facing properties.
Basically inside the assembly see ParentRoomInner. Outside the assembly see ParentRoom. Going to guess this isn't possible but worth a try.
I do see that there is an attribute
for stopping methods from being
viewable
(System.ComponentModel.EditorBrowsable)
but it's choices are rather slim and
don't really help.
You can use the EditorBrowsableAttribute for this:
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
public void MyMethod() {}
One thing to know, though: In c#, you will still get intellisense on the method if it is in the same assembly as the one you are working in. Someone referencing your assembly (or your project, for a project reference) will not see it though. You can also pass EditorBrowsableState.Advanced, and then you will only get intellisense if c# if you clear the HideAdvancedMembers option in Tools Options.
I haven't heard of a good way to do this in plain .NET. But, here are some ideas. Maybe one of them will work, or set you off in a direction that will be helpful.
Use FxCop, probably writing your own rule to make sure ParentRoom isn't called from the asslembly that defined it.
Look into the various post-processing projects for .NET (link design-by-contract).
Write some code inside your ParentRoom getter which will check the stack (using "new Stack()" or "new StackFrame(1)" to figure out whether the caller was from the same assembly. If so, either throw an exception or simply return ParentRoomInner.