I am trying to create a generic List, where I can pass the layout & item renderer as parameters.
Since it is not possible to pass parameters to a MXML component's Constructor, I figured I should create my List in Actionscript.
I figured it would go something like this:
public class GenericList extends List {
public function GenericList(iR:ItemRenderer, ac:ArrayCollection, layout:LayoutBase) {
super();
this.dataProvider = ac;
this.layout = ... // don't even have access to this.layout
this.itemRenderer = iR // Cannot pass itemRender
}
I would prefer to have the List in MXML (because It will be easier using states later), but If I am forced to use pure Actionscript so I can instantiate it and pass in parameters, any help would go a long way.
You cannot set the itemRenderer property of a list must implement IClassFactory. So your assignment would look like this:
public function GenericList(cf:ClassFactory, ac:ArrayCollection, layout:LayoutBase) {
And the instantiation would be:
var myList:GenericList = new GenericList( new ClassFactory( com.company.renderers.MyItemRenderer, ....);
Regarding the layout:
List essentially wraps DataGroup, so it is the datagroup's layout that you need to access. However, dataGroup will not necessarily be instantiated yet. So you might have to create a private property that you then utilize in commitProperties.
private var _myLayout:LayoutBase; (populate in constructor via getter/setter)
protected var layoutInvalidated:Boolean;
public function set myLayout( layout:LayoutBase):void {
_myLayout = layout;
layoutInvalidated = true;
}
override protected function commitProperties():void {
super.commitProperties();
if( layoutInvalidated && dataGroup && dataGroup.layout ) {
layoutInvalidated = false;
dataGroup.layout = _myLayout;
}
}
Related
I have a class like as below:
public class NodeOperator
{
private NodeInfo _nodeInfo;
public NodeOperator(NodeInfo nodeInfo)
{
_nodeInfo = nodeInfo;
}
public bool DoSomething(int dstRackId, int srcRackId, ModuleBase srcModulebase)
{
if (dstRackId == srcRackId)
{
if (srcModulebase.FieldBus.HardwareConfiguration.DdfInfo.UserDefine.InstallRestrictions.Position == ModulePosition.Right)
return true;
else
return false;
}
else
return _nodeInfo.CanAppendModule(dstRackId, srcModulebase, AppendDirection.Right);
}
}
I want to do the unit test for the DoSomething method, so I write some code as below:
public void DoSomethingTest()
{
var nodeInfo = A.Fake<NodeInfo>();
var srcModulebase = A.Fake<ModuleBase>();
A.CallTo(() => srcModulebase.FieldBus.HardwareConfiguration.DdfInfo.UserDefine.InstallRestrictions.Position).Returns(ModulePosition.Right); // throw System.Reflection.TargetException:
var nodeOperator = new NodeOperator(nodeInfo);
int dstRackId = 0;
int srcRackId = 0;
Assert.AreEqual(true, nodeOperator.DoSomething(dstRackId, srcRackId, srcModulebase));
A.CallTo(() => nodeInfo.CanAppendModule(dstRackId, srcModulebase, AppendDirection.Right)).MustNotHaveHappened();
}
In this function(DoSomething), I don't care if the moduleBase instance is correct or not. Also, I don't care if the properties inside the moduleBase have initialized or not.
So I write the below code to fake the property,
A.CallTo(() => srcModulebase.FieldBus.HardwareConfiguration.DdfInfo.UserDefine.InstallRestrictions.Position).Returns(ModulePosition.Right);
But this cause a Reflection.TargetException:'Non-static methods require targets'.
The FieldBus property for srcModulebase is null.
How can I just ignore the initialize inside the fake class and just fake the nested property which I want?
I know in this case, I can just pass the ModulePosition instead of ModuleBase, but I just want to know how to fake a nested property like this case.
I found the solution.
I need to change all the nested properties inside ModuleBase class to Interface or mark all of them to be virtual.
Then I can fake it.
As the documentation says in What members can be overridden:
Once a fake has been constructed, its methods and properties can be overridden if they are:
virtual,
abstract, or
an interface method when an interface is being faked
I'm trying to return all the properties of a class, and the return type of each property using Roslyn (not reflection..)
I've gotten close, but then I hit a property that returns an array of strings (or perhaps an enumeration?) I'm fighting with how to find out the type within the array/collection...
public class msgClass // part of a larger class, and referenced as Roslyn Document
string[] Lines {get; set;} //property in larger class of properties
...
var DocumentsInProject = await roslynUtilities.GetMembers<BasePropertyDeclarationSyntax>(msgClass);
foreach (var itemClassProperty in DocumentsInProject)
{
var itemDeclaredSymbol = semanticModelOfDoc
.GetDeclaredSymbol(itemClassProperty) as IPropertySymbol;
if (itemDeclaredSymbol == null)
throw new Exception($"property: {itemClassProperty}");
var name = itemDeclaredSymbol.Name;
//what does it return?
string returnType = string.Empty;
if (itemDeclaredSymbol.Type.IsReferenceType)
{
var typeofKind = itemDeclaredSymbol.Type.TypeKind;
var typeincollection = itemDeclaredSymbol.Type.BaseType;
var containingType = itemDeclaredSymbol.Type.ContainingType.Name;
}
else
{
returnType = itemDeclaredSymbol.Type.Name;
}
}
If it isn't obvious this is isn't production code - I'm hacking as I'm new to Roslyn, and I'm working on building a Visual Studio add-in that is reviewing classes in a project.
You actually need to convert property type symbol to INamedTypeSymbol or to IArrayTypeSymbol. You can check that the type is generic [un]bound type by INamedTypeSymbol and try to figure out the generic type parameters. It will allow to you receive collection's element type if type not just generic type, but collection. Casting to IArrayTypeSymbol will allow to you get array's element type. So your code should look like this:
...
if (itemDeclaredSymbol.Type is INamedTypeSymbol namedType && namedType.IsGenericType)
{
// use namedType.TypeArguments if type is bound generic or namedType.TypeParameters if isn't
}
else if (itemDeclaredSymbol.Type is IArrayTypeSymbol arrayType)
{
// use arrayType.ElementType as you want
}
...
Currently i am using JpaItemWriter to write the list of objects as below which is working fine.
Now i want to change the JpaItemWriter to JdbcBatchItemWriter due to performance issue.
public class MyItemWriter implements ItemWriter<List<MyDomainObject>> {
#Override
public void write(List<? extends Lists<MyDomainObject>> items) {
JpaItemWriter<MyDomainObject> writer = new JpaItemWriter<>();
for(List<MyDomainObject> o : items)
{
writer.write(o);
}
}
}
Suggest a sample snippets which uses the JdbcBatchItemWriter to write the List of objects will helps. Tried using the ItemSqlParameterSourceProvider it did't help ending up in org.springframework.dao.InvalidDataAccessApiUsageException: No value supplied for the SQL parameter exception
You example is not correct. You are creating a JpaItemWriter in the write method, so a new instance is created on each call to write. This is probably the cause of your performance issue.
More importantly, lifecycle methods of the delegate writer (open/update/close) will not be honored (it is not the case for JpaItemWriter which does not implement ItemStream but this would be a problem if the delegate is an item stream). Your MyItemWriter implementation should be something like:
public class MyItemWriter implements ItemWriter<List<MyDomainObject>> {
private JpaItemWriter jpaItemWriter;
public MyItemWriter(JpaItemWriter jpaItemWriter) {
this. jpaItemWriter = jpaItemWriter;
}
#Override
public void write(List<? extends Lists<MyDomainObject>> items) {
for(List<MyDomainObject> o : items) {
this. jpaItemWriter.write(o);
}
}
}
Now if you want to use the JdbcBatchItemWriter to write a list of lists, see Spring Batch - Using an ItemWriter with List of Lists.
Edit: Added a sample code of how to set the delegate as requested in comments:
#Bean
public ListUnpackingItemWriter<T> itemWriter() {
JdbcBatchItemWriter<T> jdbcBatchItemWriter = null; // configure your jdbcBatchItemWriter
ListUnpackingItemWriter<T> listUnpackingItemWriter = new ListUnpackingItemWriter<>();
listUnpackingItemWriter.setDelegate(jdbcBatchItemWriter);
return listUnpackingItemWriter;
}
Current working on creating a Prism.DryIoc.Forms project to try out DryIoc (first time!).
In Xamarin.Forms there is a native DependencyService and to provide a nice way to migrate towards using Prism I would like to add it as a fallback container in case the requsted service type can't be resolved from the main container.
Current I have created a FallbackContainer and pass the instance of IContainerand overrides the methods for IResolver and delegates the rest of the IContainer calls to the instance passed during creation.
So after the default container is created and configured and then do
Container = CreateContainer();
ConfigureContainer();
Container.Rules.WithFallbackContainer(new DependencyServiceContainer(Container));
Is this the preferred method or is there any way just to attach a default IResolver?
Current implementation
public class FallbackDependencyServiceContainer : IContainer
{
private readonly IContainer container;
public FallbackDependencyServiceContainer(IContainer container)
{
this.container = container;
}
public object Resolve(Type serviceType, bool ifUnresolvedReturnDefault)
{
return ResolveFromDependencyService(serviceType);
}
public object Resolve(Type serviceType, object serviceKey, bool ifUnresolvedReturnDefault,
Type requiredServiceType,
RequestInfo preResolveParent, IScope scope)
{
return ResolveFromDependencyService(serviceType);
}
public IEnumerable<object> ResolveMany(Type serviceType, object serviceKey, Type requiredServiceType,
object compositeParentKey,
Type compositeParentRequiredType, RequestInfo preResolveParent, IScope scope)
{
return new[] { ResolveFromDependencyService(serviceType) };
}
private static object ResolveFromDependencyService(Type targetType)
{
if (!targetType.GetTypeInfo().IsInterface)
{
return null;
}
var method = typeof(DependencyService).GetTypeInfo().GetDeclaredMethod("Get");
var genericMethod = method.MakeGenericMethod(targetType);
return genericMethod.Invoke(null, new object[] { DependencyFetchTarget.GlobalInstance });
}
....
}
Thanks and looking forward to test DryIoc since I've read it's supposed to be the fastest out there
Updated answer:
You may directly use WithUnknownServiceResolvers returning DelegateFactory:
var c = new Container(Rules.Default.WithUnknownServiceResolvers(request =>
new DelegateFactory(_ => GetFromDependencyService(request.ServiceType))));
No need to implement IContainer just for that.
I think it may be optimized regarding performance by replacing DelegateFactory with ExpressionFactory. But I need some time to play with the idea.
I am pulling my hair out with this one. I have looked and cannot find a simple, clear example of creating and using a partial stub with Microsoft Moles. Maybe I'm missing somethimg, or have my code architected poorly, but I can't seem to get this to work.
Here's my class (simplified):
public class AccountService : IAccountService {
private readonly webServiceProxy IExternalWebServiceProxy;
public AccountService(IExternalWebServiceProxy webServiceProxy) {
this.webServiceProxy = webServiceProxy;
}
public List<AccountModel> GetAccounts(string customerId) {
var returnList = new List<AccountModel>();
var xmlResponse = webServiceProxy.GetAllCustomerAccounts(customerId);
var accountNodes = xmlResponse.SelectNodes("//AccountNodes");
if (accountNodes != null)
{
foreach (XmlNode node in accountNodes)
{
var account = this.MapAccountFromXml(node);
if (!string.IsNullOrEmpty(account.AccountNumber))
{
returnList.Add(account);
}
}
}
return returnList;
}
public AccountModel MapAccountFromXml(XmlNode node) {
if (!IsValidAccount(node) {
return null;
}
// This performs a lot of XML manipulation getting nodes based on attributes
// and mapping them to the various properties of the AccountModel. It's messy
// and I didn't want it inline with the other code.
return populatedAccountModel;
{
public bool IsValidAccount(XmlNode node)
{
var taxSelectValue = node.SelectSingleNode("//FORMAT/Field[#taxSelect='1']").First().Value;
var accountStatus = // similar to first line in that it gets a single node using a specific XPath
var maturityDate = // similar to first line in that it gets a single node using a specific XPath
var maturityValue = // similar to first line in that it gets a single node using a specific XPath
return taxSelectValue != string.Empty && taxSelectValue != "0" && (accountStatusValue != "CL" || (maturityDate.Year >= DateTime.Now.AddYears(-1).Year));
}
}
What I want to do is test my GetAccounts() method. I can stub out the IExternalWebServiceProxy call and return fake XML, but I have internal calls happening in my service since my GetAccounts() method calls MapAccountFromXml() which in turn calls IsValidAccount().
Perhaps the solution is to not worry about breaking out the long and involved MapAccountFromXml() and IsValidAccount() code and just put them inline into the GetAccount() call, but I would rather leave them broken out for code readability.
I have my Moles assembly created, and know I can create a stub version of my class like this
var stubWebService = SIExternalWebServiceProxy {
GetAllCustomerAccounts = delegate {
return SomeHelper.GetFakeXmlDocument();
}
}
var stubAccountService = new SAccountService() { callsBase = true; }
My problem is I don't know how to then override the internal calls to MapAccountFromXml and IsValidAccount and I don't want my Unit Test to be testing thos methods, I'd like to isolate GetAccounts for the test. I read somewhere the methods need to be virtual to be overriden in a partial stub, but could not find anything that then showed how to create a stub that overrides a few methods while calling the base for the one I want to test.
Peer put me on the right track, thank you.
It turned out that what I was looking for is called Detours in Moles. Rather than stub an interface using
var stubAccountService = new SIAccountService();
what I needed to do was create an instance of my AccountService and then detour all calls to the methods I wanted to mock, like this
var accountService = new AccountService();
MAccountService.AllInstances.MapAccountFromXmlXmlNode = delegate {
return new AccountModel();
};
The MAccountService is provided by Moles when you Mole your assembly. The only missing piece to this is that for this to work you need to add the following attribute to your test method:
[HostType("Moles")]
This worked for me locally, but in the end I had trouble getting TFS to do automated builds
UPDATE
I just stumbled on another way of doing this, while looking at Rhino Mocks. If the methods in the class being mocked are virtual then you can override them in the mock, like this:
var accountService = new SAccountService();
accountService.MapAccountFromXmlXmlNode = delegate
{
return new AccountModel();
}
Now I can call
accountService.GetMemberAccounts();
and when accountService makes its call to MapAccountFromXml it will be caught by the stub and processed as I deem necessary. No messing with HostType and it works like a charm.
To test methods in you class in issolation you do this with moles by making a mole for the IsValidAccount and MapAccountFromXml methods. Or make a stub implementation with stubs where you let the stub call the orriginal methode using base. Or what I think is a nicer solution, make a test class which overrides the methods you do want to stub (this is the same what a stub would do, except you see all what is happening in your own code):
public class TestHelperAccountService : AccountService {
public override AccountModel MapAccountFromXml(XmlNode node) {
return new AccountModel(){
//Accountmodelstub
};
{
public override bool IsValidAccount(XmlNode node)
{
return true;
}
}
This way you can do your test for the GetAccount method on your TestHelperAccountService class where you GetAccount method runs in full issolation. You can do the same for the methods like MapAccountFromXml to test them seperatly.