示例#1
0
        public static string[] FixAnnotation(Type type, params string[] annotations)
        {
            Injectable constructor = type.GetConstructorFunction();

            string[] parameters = null;

            if (annotations != null && annotations.Length > 0)
            {
                // annotations are specified as argument
                parameters = annotations;
            }
            else
            {
                var attrs = type.GetCustomAttributes(typeof(InjectAttribute), true);
                if (attrs.Length != 0)
                {
                    // annotations are specified with the [Inject] decorator
                    parameters = (attrs[0] as InjectAttribute).Injectables;
                }
                // TODO check Inject attribute in constructors too?
                else
                {
                    // annotations are read from constructor parameter names
                    // fix "$" in parameter names
                    parameters = PatchDollarName(Angular.Injector().Annotate(constructor));
                }
            }

            // annotations are stored in type.$inject
            constructor.Inject = parameters;

            return(parameters);
        }
示例#2
0
        // Providers are injectable classes containing a callable method that returns a new instance of the service.
        // Both the class and the factory methods have different injections because they are called at distinct times.
        // The class (constructor function) is called at config phase, while the method is called when the service
        // needs to be instantiated. For convention, the class must me named with suffix "Provider" and the method
        // must be of equal name without the suffix (e.g. "UserProvider" and "User").

        public static void Provider <T>(this Module module, params string[] annotations)
        {
            Type type       = typeof(T);
            var  parameters = FixAnnotation(type, annotations);
            var  plist      = CommaSeparatedList(parameters);

            string providerName = type.FullName;

            if (!providerName.EndsWith("Provider"))
            {
                throw new Exception("provider names must end with the suffix 'Provider'");
            }
            string serviceName = providerName.Substring(0, providerName.Length - 8);

            string[] annotations_factory_method = null;

            Function factory_method = type.GetMethodAsFunction(serviceName);

            if (Angular.IsUndefined(factory_method))
            {
                throw new Exception("provider class must contain a factory method named '" + serviceName + "'");
            }

            // looks for factory method, and its Inject attribute
            foreach (var method in type.GetMethods(BindingFlags.Instance | BindingFlags.Public))
            {
                if (method.Name == serviceName)
                {
                    object[] attrs = method.GetCustomAttributes(typeof(InjectAttribute));
                    if (attrs != null && attrs.Length > 0)
                    {
                        InjectAttribute attr = attrs[0] as InjectAttribute;
                        annotations_factory_method = attr.Injectables;
                        break;
                    }
                }
            }

            if (annotations_factory_method == null)
            {
                // if [Inject] was not specified, look for inline annotations
                annotations_factory_method = PatchDollarName(Angular.Injector().Annotate(factory_method));
            }

            // Inject annotations for the factory method
            Injectable.From(factory_method).Inject = annotations_factory_method;

            // creates a wrapped function around the provider class. The provider class in instantiated and the $get is filled.
            string   body = "var $ob = new " + type.FullName + "(" + plist + "); $ob.$get = $ob." + serviceName + "; return $ob;";
            Function F    = new Function(parameters, body);

            Injectable.From(F).Inject = parameters;

            Provider(module, serviceName, F);
        }
示例#3
0
        public static void Config <T>(this Module module, params string[] annotations)
        {
            Type type       = typeof(T);
            var  parameters = FixAnnotation(type, annotations);
            var  plist      = CommaSeparatedList(parameters);

            // "run" function are called without a "this" reference, so we need to instantiate the class with "new"
            string   body = "{ new " + type.FullName + "(" + plist + "); }";
            Function F    = new Function(parameters, body);

            Injectable.From(F).Inject = parameters;
            Config(module, F);
        }