Custom Neo4j GraphViz Writer - configuration

I have an application which produces a GraphViz dot file for a subgraph of my Neo4j database. It works like a charm, but there is somewhat of an issue.
Right now, the title of each node is the node id. Then the properties are listed, with their respective types. This is more information than I need and I would like to change the way the GraphViz writer is configured.
I noticed several classes/interfaces such as GraphStyle, StyleParameter, StyleConfiguration but I've tried several things and keep running into the issue that I cannot access certain classes/interfaces outside of their respective package. Maybe I'm doing it wrong, maybe it's designed so users cannot reconfigure the GraphViz writer, I don't know but I'd like to know.
How do I reconfigure the GraphViz writer so the dot file contains only that information which I want it to contain, namely a property of my choosing as the title, and nothing else as far as the nodes are concerned. Also, this is not always the same property, so for some nodes I'd like property A to be the title, and for nodes that don't have property A, I'd like property B to be the title.
Any help would be greatly appreciated.

You could try using the styles provided by this class: https://github.com/neo4j/neo4j/blob/master/community/graphviz/src/main/java/org/neo4j/visualization/graphviz/AsciiDocSimpleStyle.java
It might be useful to look into this class as well: https://github.com/neo4j/neo4j/blob/master/community/graphviz/src/main/java/org/neo4j/visualization/asciidoc/AsciidocHelper.java

I managed to get it to work. First of all, you need to create two new classes:
class NodeStyleImpl implements NodeStyle
class RelationshipStyleImpl implements RelationshipStyle
Here you can define how nodes and relations should be written in the dot notation. An example implementation looks like this :
public class NodeStyleImpl implements NodeStyle {
public void emitNodeStart(Appendable apndbl, Node node) throws IOException {
apndbl.append(" N" + node.getId() + " [\n label = \"");
}
public void emitEnd(Appendable apndbl) throws IOException {
apndbl.append("\"\n]\n");
}
public void emitProperty(Appendable apndbl, String propkey, Object propvalue) throws IOException {
if(propkey.equals("propkeyone") || propkey.equals("propkeytwo"){
apndbl.append(propvalue.toString());
}
}
}
In an analog fashion, you can write the RelationshipStyleImpl. If you're looking for more advanced configuration, you can also write a StyleConfiguration implementation. You can look at the default implementations in the Neo4j code for an example.
Then there's the issue with the GraphStyle class. The GraphStyle class has a constructor which is protected, thus only accessible from within the package. I made a pull request to change it to public but for the moment, here's a little "hack" which provides a workaround.
package org.neo4j.visualization.graphviz
public class GraphStyleImpl extends GraphStyle {
private GraphStyleImpl (NodeStyleImpl nstyle, RelationshipStyleImpl rstyle) {
super(nstyle, rstyle);
}
}
Note the package declaration. Because the GraphStyle constructor is protected, the super(nstyle, rstyle) method is only accessible from within the same package. By extending the class with a new public constructor, you can now do the following:
GraphStyle graphstyle = new GraphStyleImpl(new NodeStyleImpl(), new RelationshipStyleImpl());
GraphvizWriter writer = new GraphvizWriter(graphstyle);
If my pull request gets accepted, the use of the GraphStyleImpl class will no longer be necessary.

Related

Factory to return array of IItem from single object

This is a simplified version of the problem i am solving but conceptually equivalent.
This project is using castle windsor and I am trying to keep all factories in the container.
I have a single object that represents data parsed from a text file. After parsing this file I need to write a new text file with 2 line based on data in the original object.
lets say the text file is
Some Person, Work Phone, Mobil Phone
this gets parsed into
public class Person
{
public string Name{get;set;}
public stirng WorkPhone {get;set;}
public stirng MobilPhone {get;set;}
}
Now this is a simplified example so keep that in mind please. The next step is to creat new object instances that represent each line we will write to the text file
public interface IFileEntry
{
string Name{get;set;}
string Number{get;set;}
}
public class PersonWorkPhoneEntry : IFileEntry
{
public string Name {get;set;}
public string Number{get;set;}
public override ToString(){....}
}
public class PersonMobilPhoneEntry: IFileEntry
{
public string Name{get;set;}
public string Number{get;set;}
public override ToString(){....}
}
so being that we are using Castle for this lets make a factory
public interface IFileEntryFactory
{
IFileEntry Create(string entryType, stirng Name, string Number
}
I have created my own implementation for the DefaultTypedFactoryComponentSelector and install that for this factory only.
public class FileEntryComponentSelector : DefaultTypedFactoryComponentSelector
{
protected override string GetComponentName(System.Reflection.MethodInfo method, object[] arguments)
{
if (method.Name == "Create" && arguments.length == 3)
{
return (string)arguments[0];
}
return base.GetComponentName(method, arguments);
}
}
This works,
var workEntry = _factory.Create("PersonWorkPhoneEntry", person.Name, person.WorkPhone)
var mobilEntry = _factory.Create("PersonMobilPhoneEntry", person.Name, person.WorkPhone)
//then write the tostring to a text file
Sorry for the long setup but i think its needed. What I am trying to do Is
public interface IFileEntryFactory
{
IFileEntry Create(string entryType, stirng Name, string Number
IFileEntry[] Create(Person person)
}
var entries = _factory.Create(person);
foreach(var e in entries)
///write to text file.
I have been digging all over for a solution like this with no results.
What seems to be a possible solution taking the example shown here (Castle Windsor Typed Factory Facility with generics)
Im currently working on implementing something like this now, not sure if this is the right way to solve this problem.
The questions:
are there any other ways to have the factory return the array of
needed objects
what is the best practice for solving something like
this
any examples and reading for advanced factories
It is possible to make a Factory return to you an array of objects which are already registered in the container. Here is an example
container.Register(Component.For<IMyStuffProvider>().AsFactory()) // registration
public interface IStuffProvider
{
IEnumerable<IMyStuff> GetAllStuff();
void Release(IMyStuff stuff);
}
This code makes possible that every registered implementation of IMyStuff gets returned by the factory.
But I think that your problem is different : you are using the factory for the wrong purpose. TypedFactory is to get instances of objects that are already registered in the container during app start and not to manipulate files. Their purpose is to solve problems regarding dependencies.
If you are parsing a csv/txt into objects and then writing some of the rows back into another csv/txt you have to make
IFileEntryManager (with an implementation) with a methods like DeserializeFileToObjects, WriteObjectsToFile, etc.
IFileEntryManagerFactory to create and return IFileEntryManager. ( Castle typed factory here :) )
Now inject your IFileEntryManagerFactory in your ctor of the class that needs to serialize/deserialize text files and and use it to get your FileEntryManager which in turn will act upon your text files.
If you have different objects like Person, Company, Employee... etc. and you want to handle them with generic manipulator - it is ok. The best way is to implement a Generic Repository. Lets say ICsvRepository<T>. Just search for 'Generic Rpository in c#' and ignore that fact that most of the implementation examples are with EntityFramework as a persistence store. Behind the interface you can make it read/write to csv rather than to DB.
Lets generalize it. If you have to deal with resources - files, sql, blobs, tables, message bus or whatever resource persistent/non persistent which comes in or goes out of your application you have to manipulate it through an abstraction IMyResourceManager with its corresponding manipulation methods. If you have several implementations of IMyResourceManager and you want to decide during runtime which implementation you want then you have to make IMyResourceManagerFactory with a component selector or factory method and place your differentiation logic there.
That is why I think you do not need a TypedFactory for text file read/write but a pure ITextFileManipulator which you have to register in the container and get it through constructor. You may need a typed factory if you go for ICsvRepository<T> where T is your Person class. Inside the implementation of ICsvRepository<T> you will need ICsvFileManipulator.

How can I wrap a JSON response in Spring

Suppose I have two sets of controllers in Spring:
/jsonapi1/*
/jsonapi2/*
both of which return objects that are to be interpretted as JSON text.
I'd like some kind of filter to wrap the responses from one set of these controllers so that:
the original response is contained within another object.
For example, if /jsonapi1/count returns:
{"num_humans":123, "num_androids":456}
then the response should be wrapped and returned as follows:
{ "status":0,
"content":{"num_humans":123, "num_androids":456}
}
if an exception happens in the controller, then filter should catch the exception and report it as follows
{ "status":5,
"content":"Something terrible happened"
}
The responses from the other controllers are returned unchanged.
We're currently customizing a MappingJackson2HttpMessageConverter passed to WebMvcConfigurerAdapter.configureMessageConverters in order to perform the above tasks. Works great except that it doesn't seem possible for this approach to be selective about the URLs (or controller classes) it applies to.
Is it possible to apply these kinds of wrappers to individual controller classes or URLs?
Update: Servlet filters look like a solution. Is it possible chose which filter gets applied to which controller methods, or which URLs?
I was struggling on this for multiple days. The solution by #Misha didn't work for me. I was able to finally get this working using ControllerAdvice and ResponseBodyAdvice.
ResponseBodyAdvice allows to inject custom transformation logic on the response returned by a controller but before it is converted to HttpResponse and committed.
This is how my controller method looks:
#RequestMapping("/global/hallOfFame")
public List<HallOfFame> getAllHallOfFame() {
return hallOfFameService.getAllHallOfFame();
}
Now i wanted to add some standard fields around the response like devmessage and usermessage. That logic goes into the ResponseAdvice:
#ControllerAdvice
public class TLResponseAdvice implements ResponseBodyAdvice<Object> {
#Override
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
return true;
}
#Override
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request,
ServerHttpResponse response) {
// TODO Auto-generated method stub
final RestResponse<Object> output = new RestResponse<>();
output.setData(body);
output.setDevMessage("ResponseAdviceDevMessage");
output.setHttpcode(200);
output.setStatus("Success");
output.setUserMessage("ResponseAdviceUserMessage");
return output;
}
}
The entity classes look like this:
#Setter // All lombok annotations
#Getter
#ToString
public class RestResponse<T> {
private String status;
private int httpcode;
private String devMessage;
private String userMessage;
private T data;
}
#Entity
#Data // Lombok
public class HallOfFame {
#Id
private String id;
private String name;
}
To handle exceptions, simply create another ControllerAdvice with ExceptionHandler. Use the example in this link.
Advantages of this solution:
It keeps your controllers clean. You can support any return type from your controller methods.
Your controller return type class does not need to extend some base class as required by the AOP approach.
You do not need to hack your way through Spring filters by using HttpServletResponseWrappers. They come up with a performance penalty.
EDIT - 17th September 2019
To handle exceptions use #ExceptionHandler. Refer code below.
#ExceptionHandler(Exception.class)
#ResponseBody
public MyResponseEntity<Object> handleControllerException(HttpServletRequest request, Throwable ex) {
// default value
int httpCode = HttpStatus.INTERNAL_SERVER_ERROR.value();
if(ex instanceof ResourceNotFoundException) {
httpCode = HttpStatus.NOT_FOUND.value();
}
...
}
The way I understand your question, you have exactly three choices.
Option #1
Manually wrap your objects in simple SuccessResponse, ErrorResponse, SomethingSortOfWrongResponse, etc. objects that have the fields you require. At this point, you have per-request flexibility, changing the fields on one of the response wrappers is trivial, and the only true drawback is code repetition if many of the controller's request methods can and should be grouped together.
Option #2
As you mentioned, and filter could be designed to do the dirty work, but be wary that Spring filters will NOT give you access to request or response data. Here's an example of what it might look like:
#Component
public class ResponseWrappingFilter extends GenericFilterBean {
#Override
public void doFilter(
ServletRequest request,
ServletResponse response,
FilterChain chain) {
// Perform the rest of the chain, populating the response.
chain.doFilter(request, response);
// No way to read the body from the response here. getBody() doesn't exist.
response.setBody(new ResponseWrapper(response.getStatus(), response.getBody());
}
}
If you find a way to set the body in that filter, then yes, you could easily wrap it up. Otherwise, this option is a dead end.
Option #3
A-ha. So you got this far. Code duplication is not an option, but you insist on wrapping responses from your controller methods. I'd like to introduce the true solution - aspect-oriented programming (AOP), which Spring supports fondly.
If you're not familiar with AOP, the premise is as follows: you define an expression that matches (like a regular expression matches) points in the code. These points are called join points, while the expressions that match them are called pointcuts. You can then opt to execute additional, arbitrary code, called advice, when any pointcut or combination of pointcuts are matched. An object that defines pointcuts and advice is called an aspect.
It's great for expressing yourself more fluently in Java. The only drawback is weaker static type checking. Without further ado, here's your response-wrapping in aspect-oriented programming:
#Aspect
#Component
public class ResponseWrappingAspect {
#Pointcut("within(#org.springframework.stereotype.Controller *)")
public void anyControllerPointcut() {}
#Pointcut("execution(* *(..))")
public void anyMethodPointcut() {}
#AfterReturning(
value = "anyControllerPointcut() && anyMethodPointcut()",
returning = "response")
public Object wrapResponse(Object response) {
// Do whatever logic needs to be done to wrap it correctly.
return new ResponseWrapper(response);
}
#AfterThrowing(
value = "anyControllerPointcut() && anyMethodPointcut()",
throwing = "cause")
public Object wrapException(Exception cause) {
// Do whatever logic needs to be done to wrap it correctly.
return new ErrorResponseWrapper(cause);
}
}
The final result will be the non-repeating response wrapping that you seek. If you only want some or one controller receive this effect, then update the pointcut to match methods only within instances of that controller (rather than any class holding the #Controller annotation).
You'll need to include some AOP dependencies, add the AOP-enabling annotation in a configuration class, and make sure something component-scans the package this class is in.
Simplest way i manage custom responses from controllers is by utilising the Map variable.
so your code ends up looking like:
public #ResponseBody Map controllerName(...) {
Map mapA = new HashMap();
mapA.put("status", "5");
mapA.put("content", "something went south");
return mapA;
}
beauty of is is that you can configure it any thousand ways.
Currently i use for object transmition, custom exception handling and data reporting, too easy.
Hope this helps
I am also using AOP with #Around. Developed a custom annotation and using that for point cut. I am using a global Response. It has the status, Message and data which is of type List of type
List <? extends parent> dataList
( which can solve your class cast exception). All the entities extends this Parent class. This way I can set all the data into my List.
Also I am using the message key as param with the custom annotation and setting it in action.
Hope this helps.

How Actionscript 3 Classes Work

I need a little help understanding how classes work in Actionscript 3. I understand you start with "package" and why and then go to import any necessary libraries, as well as then naming the class and stating if it's public/private and extends anything.
After that is what I don't understand. It seems you write "(public) function class name()
I don't understand why you do this and what goes in the curly brackets.
I've probably missed a bit of earlier reading because I've done a little reading but I can't seem to get it.
Could someone try explain it to me? Thanks.
ActionScript 3 Classes
The package statement.
Okay, so firstly like you mentioned, a class must be wrapped by a package1. This gives us the first block, where you need to define the class.
package
{
// Your class here.
}
The package statement reflects the location of the class relative to the .fla2. For example, if you have a folder "classes" within the same directory as the project .fla, then classes within that folder will need a package statement that reflects that:
package classes
{
// Your class here.
}
Defining the class.
Within a package statement, you may insert one class. Do not confuse this with the package itself, which can contain many classes - each class just needs to have its own file with the same package statement.
A class definition is made up of up to 5 parts:
The namespace. A class can be internal or public. An internal class can only be seen by classes within the same package, whereas public classes can be seen from anywhere in the project.
The class name.
A base class (optional). If a base class is defined, then your new class will act as an extension to that class, inheriting all of the qualities of the base class.
An interface to implement (optional). Interfaces are an advanced topic thus I suggest you forget about these for now until your AS3 and OOP have evolved.
If you wanted to create a class called "Person" within the package classes, then we would end up with:
package classes
{
public class Person
{
// Class qualities here.
}
}
Properties.
Classes can contain properties. Properties are defined using the var keyword. They may belong to one of a number of namespaces (including your own) and are used to hold values that belong to your class. Properties are most commonly found clustered together at the top of your class.
Our Person class may enjoy the properties height and weight:
package classes
{
public class Person
{
// Properties.
public var height:Number = 1.70;
public var weight:Number = 67.5;
}
}
These properties can be accessed via any instance of Person that you create. Each instance will have its own set of these properties.
Class constructors (I believe this is what you're asking about).
Constructors are used to hold logic that should be run as soon as an instance of your class is created. The class constructor has the same name as the class itself. It must be public and it does not return anything. Constructors can accept arguments, which are typically used to pass in references to dependencies for that class or required values.
package classes
{
public class Person
{
// Properties.
public var height:Number = 1.70;
public var weight:Number = 67.5;
// Constructor.
public function Person(height:Number, weight:Number)
{
this.height = height;
this.weight = weight;
}
}
}
Methods.
Methods are used to hold logic that can be run when calling that method. Methods often return values and can accept arguments. Methods can belong to any namespace that you would expect properties to be able to belong to.
We may want to be able to easily determine the BMI of each instance of Person that we create, so we should create a method for that:
package classes
{
public class Person
{
// Properties.
public var height:Number = 170;
public var weight:Number = 65.5;
// Constructor.
public function Person(height:Number, weight:Number)
{
this.height = height;
this.weight = weight;
}
// Determine my BMI and return the result.
public function getBMI():Number
{
return weight / (height * height);
}
}
}
Instances.
Now that we've defined our new class, we can create instances of this class using the new keyword. This can be done from anywhere that can access the Person class, which in this case is anywhere in the project because we've made the class public.
Though the class is public, accessing it from anywhere outside of the package it belongs in will require the use of an import statement. This statement will need to be used within any class that belongs to a different package. The import statement follows the same name used for the package and includes the name of the class you want to include on the end:
import classes.Person;
Once you've imported Person, you can create instances of it and assign them to a variable with different height and weight values:
var marty:Person = new Person(71, 1.76);
var bruce:Person = new Person(96.4, 1.72);
We can then obtain the BMI for each person using their getBMI() method:
trace(marty.getBMI()); // 22.9
trace(bruce.getBMI()); // 32.6
1 You can place classes outside of a package which can be referred to in the same .as file.
2 You can add more source paths, and packages can be relative to that.
The function that have the same name as class is a constructor. In curly brackets is basically part of code that will execute instantly when object will be created. Try to search info about constructors, they exist I think in every object oriented programming language (I may be wrong), so you have a lot of resources.
You can also read about this concept on Wikipedia.
The function that is named the same as the class is the constructor. It's optional, so you can leave it out if you don't need it. A default constructor will be added, which essentially does nothing.
The constructor lets you write code that executes immediately after an instance of the class is created (ie when another bit of code runs new ClassName(). You would typically use it to initialise some variables that are used by the class. Defining a constructor also lets you handle constructor arguments, which other code can pass when they use the new operator.

Alter ResourceManager to split values by semicolon, not comma

As the title says, is there a way to alter the ResourceManager's getStringArray() in a way that it splits the resources by semicolon, not comma?
The actual method can be found in the ResourceManagerImpl class, which can be found in in the package mx.resources.
Overriding that method would be fine, but ideally I'd like to write my own getStringArray with a variable separator, however, there seems to be no way of extending either the ResourceManager or ResourceManagerImpl class to somehow add that method.
Anyone got a clue what to do here?
The problem is not that you can't extend ResourceManagerImpl since it's not final, but rather that you have to be able to register your implementation with the application instead of the default one. And doing this is a bit tricky.
So first create your implementation:
public class MyResourceManager extends ResourceManagerImpl {
private static var instance:IResourceManager;
static public function getInstance():IResourceManager
{
if (!instance) instance = new MyResourceManager();
return instance;
}
override public function getStringArray(bundleName:String,
resourceName:String,
locale:String = null):Array {
//do your stuff
}
}
So we've overriden the getStringArray method. Notice that we've done the same for getInstance, because we want it to return a new instance of MyResourceManager instead of ResourceManagerImpl (we don't have to mark override because it's a static method). Also, you may have to write some import statements manually, because some of the classes you're using are marked as 'excluded'.
Now we have to tell Flex to use MyResourceManager instead of ResourceManagerImpl. We can do this with the following code:
import mx.core.Singleton;
Singleton.registerClass("mx.resources::IResourceManager", MyResourceManager);
The problem is that we have to do this before Flex registers ResourceManagerImpl, because you can't override it once it's registered. For this we need to create a custom preloader in which we do the registering (sadly, the Application's 'preinitialize' phase is not early enough).
public class RegisteringPreloader extends DownloadProgressBar {
override public function initialize():void {
super.initialize();
Singleton.registerClass("mx.resources::IResourceManager",
MyResourceManager);
}
}
Now assign the custom preloader to the application and we're done:
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
preloader="RegisteringPreloader" >
For further info I refer you to a fairly similar, but somewhat more elaborate answer that I wrote for a different question: Is there a way to listen for events on the pop up manager class?
Just for the record: if you want to provide your localization with array of strings containing commas, it is way easier to use getObject method of IResourceManager.
In your properties file:
my.beloved.strings: ["That's it, string one", "Okay, string two"]
In your code:
var strings:Array = _resourceManager.getObject(_bundleId, 'my.beloved.strings') as Array;
var stringOne:String = strings[0];
You don't have to override anything this way.

Access to global application settings

A database application that I'm currently working on, stores all sorts of settings in the database. Most of those settings are there to customize certain business rules, but there's also some other stuff in there.
The app contains objects that specifically do a certain task, e.g., a certain complicated calculation. Those non-UI objects are unit-tested, but also need access to lots of those global settings. The way we've implemented this right now, is by giving the objects properties that are filled by the Application Controller at runtime. When testing, we create the objects in the test and fill in values for testing (not from the database).
This works better, in any case much better than having all those objects need some global Settings object --- that of course effectively makes unit testing impossible :) Disadvantage can be that you sometimes need to set a dozen of properties, or that you need to let those properties 'percolate' into sub-objects.
So the general question is: how do you provide access to global application settings in your projects, without the need for global variables, while still being able to unit test your code? This must be a problem that's been solved 100's of times...
(Note: I'm not too much of an experienced programmer, as you'll have noticed; but I love to learn! And of course, I've already done research into this topic, but I'm really looking for some first-hand experiences)
You could use Martin Fowlers ServiceLocator pattern. In php it could look like this:
class ServiceLocator {
private static $soleInstance;
private $globalSettings;
public static function load($locator) {
self::$soleInstance = $locator;
}
public static function globalSettings() {
if (!isset(self::$soleInstance->globalSettings)) {
self::$soleInstance->setGlobalSettings(new GlobalSettings());
}
return self::$soleInstance->globalSettings;
}
}
Your production code then initializes the service locator like this:
ServiceLocator::load(new ServiceLocator());
In your test-code, you insert your mock-settings like this:
ServiceLocator s = new ServiceLocator();
s->setGlobalSettings(new MockGlobalSettings());
ServiceLocator::load(s);
It's a repository for singletons that can be exchanged for testing purposes.
I like to model my configuration access off of the Service Locator pattern. This gives me a single point to get any configuration value that I need and by putting it outside the application in a separate library, it allows reuse and testability. Here is some sample code, I am not sure what language you are using, but I wrote it in C#.
First I create a generic class that will models my ConfigurationItem.
public class ConfigurationItem<T>
{
private T item;
public ConfigurationItem(T item)
{
this.item = item;
}
public T GetValue()
{
return item;
}
}
Then I create a class that exposes public static readonly variables for the configuration item. Here I am just reading the ConnectionStringSettings from a config file, which is just xml. Of course for more items, you can read the values from any source.
public class ConfigurationItems
{
public static ConfigurationItem<ConnectionStringSettings> ConnectionSettings = new ConfigurationItem<ConnectionStringSettings>(RetrieveConnectionString());
private static ConnectionStringSettings RetrieveConnectionString()
{
// In .Net, we store our connection string in the application/web config file.
// We can access those values through the ConfigurationManager class.
return ConfigurationManager.ConnectionStrings[ConfigurationManager.AppSettings["ConnectionKey"]];
}
}
Then when I need a ConfigurationItem for use, I call it like this:
ConfigurationItems.ConnectionSettings.GetValue();
And it will return me a type safe value, which I can then cache or do whatever I want with.
Here's a sample test:
[TestFixture]
public class ConfigurationItemsTest
{
[Test]
public void ShouldBeAbleToAccessConnectionStringSettings()
{
ConnectionStringSettings item = ConfigurationItems.ConnectionSettings.GetValue();
Assert.IsNotNull(item);
}
}
Hope this helps.
Usually this is handled by an ini file or XML configuration file. Then you just have a class that reads the setting when neeed.
.NET has this built in with the ConfigurationManager classes, but it's quite easy to implement, just read text files, or load XML into DOM or parse them by hand in code.
Having config files in the database is ok, but it does tie you to the database, and creates an extra dependancy for your app that ini/xml files solve.
I did this:
public class MySettings
{
public static double Setting1
{ get { return SettingsCache.Instance.GetDouble("Setting1"); } }
public static string Setting2
{ get { return SettingsCache.Instance.GetString("Setting2"); } }
}
I put this in a separate infrastructure module to remove any issues with circular dependencies.
Doing this I am not tied to any specific configuration method, and have no strings running havoc in my applications code.