i have a problem with db4o and I wanna know is it feature or bug.
Let's see some code
private interface IInterface {}
private class SimpleObject : IInterface
{}
[TestMethod, Ignore]
public void _()
{
var replicableServer = Db4oFactory.OpenServer(Path.GetFullPath(#"testdb"), 777);
try
{
replicableServer.GrantAccess("user", "user");
var client2 = Db4oFactory.OpenClient("127.0.0.1", 777, "user", "user");
var client1 = Db4oFactory.OpenClient("127.0.0.1", 777, "user", "user");
client1.Store(new SimpleObject());
client1.Commit();
var query = client2.Query();
query.Constrain(typeof(IInterface));
Assert.AreEqual(1, query.Execute().Count);
}
finally
{
replicableServer.Close();
}
}
Here we have failed assert. But if we change type in constraint to SimpleObject, all would work fine. This is strange and I can't find reason to this.
Thank guys. But we solved this riddle. Problem was, that db4o saving information about object and what interface it implement, only after first save.
So, we simple saved all our empty objects to base, before work with it.
I don't know exactly how db4o works, but having written a document db, I can say it's unlikely that db4o stores the entire type hierarchy. It will only keep track of the type that was used to store the data. This is really only for serialization in my case.
To make something like this work, you would likely need to build your own index. When an object is stored, for each type in the hierarchy (except Object and IDisposable I expect) update a record like new TypeIndex { IndexedType = typeof(IInterface), ActualKey = ... }.
Related
We have an extension method that accepts an action to initialize an object.
Is there some way to improve the syntax of such a call:
public static T NewRow<T>(this IUow uow, Action<T> action();
// this does internally call
public T NewRow<T>(Action<T> initializer) where T : IBo
{
T bo = NewRow<T>();
initializer.Invoke(bo);
return bo;
}
uow.NewRow<ICustomer>(customer => {
customer.Name = "Zzz";
customer.Info = "Abc"
);
I thought maybe I could use something similar to the object initializer syntax?
uow.NewRow<ICustomer>({
Name: "Zzz",
Info: "Abc"
});
The idea is to get rid of customer.* = ... in every line.
I would be happy for any tip.
INFO:
We are using the latest C# language version
The solution should support IntelliSense (e.g., Name and Info should be proposed to the user)
Edit:
I can't use a constructor because I only have an interface. No class/implementation. The framework behind creates the object to the given interface T bo = NewRow<T>();. Which actual object gets created is decided by the framework
Also initializers like { Name: myOtherVariable.FirstName } should be possible
an Action could be everything, not just a simple assignment. So if a client chosed to make a function-call instead, there literally is nothing to shortcut here. See this for example:
uow.NewRow<IWhatever>(() => Console.WriteLine("tataaaa"););
So no, what you want isn't possible.
However you could create some kind of EventsArgs that hold your names and use those within your NewRow-method. There's no need for an action if all those callbacks should actually be just assignement-calls alltogether.
uow.NewRow<ICustomer>(new MyArgs {
Name = "Zzz",
Info = "Abc"
});
And within NewRow:
public T NewRow<T>(MyArgs args) where T : IBo
{
customer.Name = args.Name;
customer.Info = args.Info;
}
I receive data from a DB. There will be only one model at a time which I call currentModel from now on. The type of model received must be determined at runtime. Therefore, I implemented an Interface for the models IDataModel. Each possible model implements IDataModel. There is a variable which holds the currentModel. In order to make it generic I defined it as IDataModel. Here is the code so far.
public async Task<List<T>> LoadData<T, U>(string sql, U parameters, string connectionString)
{
using (IDbConnection connection = new SqlConnection(connectionString))
{
var rows = await connection.QueryAsync<T>(sql, parameters);
return rows.ToList();
}
}
private IDataModel currentModel;
private List<IDataModel> queryResult;
if (someCondition)
{
currentModel = newSpecificModel();
sql = someQuery;
}
else ....
queryResult = await _data.LoadData<IDataModel, dynamic>(sql, new {}, config.GetConnectionString("default"));
if (queryResult.Count == 1)
{
currentModel= queryResult.First();
}
else
{
// Do error handling here if more than one row is returned from the query
}
Now when I try to access some property I get an error: IDataModel does not contain a definition for someProperty
currentModel.someProperty
How do I determine the current implementation at runtime?
I mean I could create a variable for each possible model. But is there a more elegant way?
EDIT
Nailed the problem down to that this wont work:
List<Interface> = List<Implementation>
See this post.
Whats an approach to solve this?
Have a look at the curiously recurring template pattern; it is useful for creating child objects with the right type.
Maybe also look at this discussion.
I'm having trouble with some syntax. I'm not really familiar with interfaces so please excuse my ignorance.
VS2010 is giving me an error at... application.Name = System.AppDomain.CurrentDomain.FriendlyName;
public static void AddApplication(string applicationName = null, string processImageFileName = null)
{
INetFwAuthorizedApplications applications;
INetFwAuthorizedApplication application;
if(applicationName == null)
{
application.Name = System.AppDomain.CurrentDomain.FriendlyName;/*set the name of the application */
}
else
{
application.Name = applicationName;/*set the name of the application */
}
if (processImageFileName == null)
{
application.ProcessImageFileName = System.Reflection.Assembly.GetExecutingAssembly().Location; /* set this property to the location of the executable file of the application*/
}
else
{
application.ProcessImageFileName = processImageFileName; /* set this property to the location of the executable file of the application*/
}
application.Enabled = true; //enable it
/*now add this application to AuthorizedApplications collection */
Type NetFwMgrType = Type.GetTypeFromProgID("HNetCfg.FwMgr", false);
INetFwMgr mgr = (INetFwMgr)Activator.CreateInstance(NetFwMgrType);
applications = (INetFwAuthorizedApplications)mgr.LocalPolicy.CurrentProfile.AuthorizedApplications;
applications.Add(application);
}
I can make that error go away by setting application to null but that causes a run-time null reference error.
Edit:
Here's where I'm adapting the code from. I hope it gives more context
http://blogs.msdn.com/b/securitytools/archive/2009/08/21/automating-windows-firewall-settings-with-c.aspx
You never initialize
application
before using it here:
application.Name = System.AppDomain.CurrentDomain.FriendlyName;
The variable application is defined as:
INetFwAuthorizedApplication application
You need to assign an instance of a class that implements the interface INetFwAuthorizedApplication.
Somewhere there must be one (or probably more) classes in your project that look something like this:
public class SomeClass : INetFwAuthorizedApplication
{
// ...
}
public class AnotherClass : INetFwAuthorizedApplication
{
// ...
}
You need to determine what class you should use (SomeClass, AnotherClass) then assign an appropriate object, e.g. like this:
INetFwAuthorizedApplication application = new SomeClass();
Interfaces are used to describe what an object does, not what it is specifically. To put into "real world" terms, an interface might be like:
ISmallerThanABreadbox with a FitIntoBreadbox() method. I can't ask you to give me "the smaller than a breadbox" ... as that doesn't make any sense. I can only ask you to give me something that "IS smaller than a breadbox". You have to come up with your own object that makes sense to have the interface on it. An apple is smaller than a breadbox, so if you have a breadbox that only holds items smaller than it, an apple is a good candidate for the ISmallerThanABreadbox interface.
Another example is IGraspable with a Hold() method and FitsInPocket bool property. You can ask to be given something that IS graspable that may or may not fit in your pocket, but you can't ask for "the graspable".
Hope that helps...
I have a three polymorphed classes. Based on user input the class should be set to that user's input. So the child class is decided by a user, and should make for 'class = new inputClass'. The snippet of code looks like:
public void characterGeneration(string classSelected)
{
foreach (string classInList in classes.ClassList)
{
if (classSelected == classInList)
{
PlayerOneStats = new Mage();
}
}
PlayerOneStats.generateStats();
}
Where it says PlayerOneStats = new Mage();, I want the Mage() to be the user input.
I've looked at Activator, Assembly, using Type, trying to cast over to the parent of GenerateStats, but nothing works. I've found many people saying it works, and one link that says it doesn't work. Can somebody please clear this up for me? Thank you very much!
Are you sure Activator doesn't work? Activator.CreateInstace("assembly-name", "type-name") seems like exactly what you want. What doesn't work?
What is the base class of Mage (and the other classes a user can select)? You should be able to do this:
public void characterGeneration(string classSelected)
{
foreach (string classInList in classes.ClassList)
{
if (classSelected == classInList)
{
PlayerOneStats = (GenerateStats)Assembly.GetExecutingAssembly().CreateInstance("YourNamespace." + classSelected);
break;
}
}
PlayerOneStats.generateStats();
}
Make sure that you include the namespace the type you want is contained in and this should work for you:
string classSelected = "testCode.Mage";
var player = Activator.CreateInstance(Type.GetType(classSelected));
Since Activator.CreateInstance() returns an object you will have to cast - in your case it would make sense to cast to an interface that all your player classes implement:
var player = (IPlayerCharacter) Activator.CreateInstance(Type.GetType(classSelected));
I have a MVC Web Application using the following approach:
public class MyController : Controller
{
public FooRepository fooRepository = new FooRepository();
public BarRepository barRepository = new BarRepository();
public ActionResult UpdateItems(int id, int range1, int range2)
{
Foo foo = fooRepository.GetItem(id);
List<Bar> bars = barRepository.GetItemsByRange(range1, range2);
// Some validation rules here...
DoSomeWork(foo, bars);
// Show confirmation / error message
}
private void DoSomeWork(Foo foo, List<Bar> bars)
{
foreach(int i = 0; i < bars.Count; i++)
{
bars[i].Prop1 = foo.Prop1; // This field is updated
bars[i].Owner = "someuser"; // This one too
bars[i].Status = BarStatus.SomeStatus; // This isn't...
}
foo.Status = FooStatus.SomeStatus; // Ok
// Calls DataContext.SubmitChanges()
fooRepository.SubmitChanges();
barRepository.SubmitChanges();
}
}
However, in some "random" cases (I see no pattern), one of the fields doesn't get updated, as noted in the comments.
It seems like LINQ isn't recognizing the field's update, so it gets excluded from the generated query.
Can anyone tell me if I'm missing something here, what could be causing it and/or how can I solve it?
Note: I don't get any Exception and can't verify this case in a development scenario.
From my experience if the error is random and you can't reproduce in development than the problem is user error.
Programming would be really hard if the .net framework or the CLR just randomly decided to do things differently.
You probably have an implicit/explicit bind exclusion floating around somewhere
[Bind(Exclude="...,Status,...")]
Just guessing of course
If Linq thinks that the Status is already BarStatus.SomeStatus, then it won't update it.
What can happen is that you find a record with the status set to this value, and then some other routine changes it, and then, if you are using your same DataContext, you will get the old value from the cached copy and hence Linq thinks that it does not need to update it.