 import Foundation
 
 private let di = DIServiceLocator()
+
+private func get_property_name<T>(_ property: T.Type) -> String {
+    let className = String(describing: property.self)
+    var chars = Array(className.characters)
+    let firstLetter = String(chars[0]).lowercased()
+    let firstLetterChars = Array(firstLetter.characters)
+    chars[0] = firstLetterChars[0]
+    let propertyName = String(chars)
+    return propertyName
+}
 
 /**
  Register a container with the DI service.

 Associate a class dependency with a value. This should only be used in test.

 */
public func di_stub(class: AnyClass, value: Any) {

}

/**
 Associate a name of a dependency with corresponding value. This should only be used in test.
 
 */
public func di_stub(name: AnyClass, value: Any) {

}

public protocol DIContainer {

/**
 Inject a dependency given the class type.

 When there is only a single instance of a given class, it is expected to name the variable the same as the class but with the first letter lowercased. For instance, the property name for the instance of 'MetricsService' will be 'metricsService'. This is provided as a convience.
 ```
 public let metricsService: MetricsService
 ```
 
 When the name of the property deviates from the name of the class you would then provide the 'name' of the public property which references the instance of the class. Below is an example where there are two instance of the `HTTPService` object. One is for HTTP, which uses the naming convention of having the first letter lowercase, and the other for HTTPS, which adds an 's' at the end of 'http'.
 ```
 public let httpService: HTTPService // Use di_inject(property: AnyClass) for this property
 public let httpsService: HTTPService // Use di_inject(name: String) for this property
 ```
 
 This is how you would inject both of these dependencies:
 ```
 class MyClass {
    private let httpService = di_inject(HTTPService.self)
    private let httpsService = di_inject(HTTPService.self, name: "httpsService")
 }
 ```
 
 - parameter property: The class of the dependency to inject.
 - parameter name: (optional) The name of the property associated to the dependency.
 - returns: The instance of the dependency. The app will crash if the dependency is not found.
 */
public func di_inject<T>(_ type: T.Type, name: String? = nil) -> T {
    if let propertyName = name {
        return di.inject(propertyName) as! T
    }
    let propertyName = get_property_name(type)
    return di.inject(propertyName) as! T
}

/**
